Remove URIBuf.

This commit is contained in:
Sergio Benitez 2016-12-21 00:20:14 -08:00
parent 62fe734492
commit dedf5094fe
3 changed files with 13 additions and 154 deletions

View File

@ -299,140 +299,6 @@ impl<'a> fmt::Display for URI<'a> {
unsafe impl<'a> Sync for URI<'a> { /* It's safe! */ }
#[derive(Debug, Clone, PartialEq, Eq)]
/// Owned string type for absolute URIs.
///
/// This is the owned analog to [URI](struct.URI.html). It serves simply to hold
/// the backing String. As a result, most functionality will be achieved through
/// the [as_uri](#method.as_uri) method.
///
/// The exception to this is the [segment_count](#method.segment_count) method,
/// which is provided here for performance reasons. This method uses a cached
/// count of the segments on subsequent calls. To avoid computing the segment
/// count again and again, use the `segment_count` method on URIBuf directly.
///
/// ## Constructing
///
/// A URIBuf can be created with either a borrowed or owned string via the
/// [new](#method.new) or `from` methods.
pub struct URIBuf {
uri: String,
segment_count: Cell<Option<usize>>,
}
impl URIBuf {
/// Construct a new URIBuf.
///
/// # Examples
///
/// From a borrowed string:
///
/// ```rust
/// use rocket::http::uri::URIBuf;
///
/// let uri = URIBuf::new("/a/b/c");
/// assert_eq!(uri.as_uri().as_str(), "/a/b/c");
/// ```
///
/// From an owned string:
///
/// ```rust
/// use rocket::http::uri::URIBuf;
///
/// let uri = URIBuf::new("/a/b/c".to_string());
/// assert_eq!(uri.as_str(), "/a/b/c");
/// ```
#[inline(always)]
pub fn new<S: Into<URIBuf>>(s: S) -> URIBuf {
s.into()
}
/// Returns the number of segments in the URI. Empty segments, which are
/// invalid according to RFC#3986, are not counted.
///
/// The segment count is cached after the first invocation. As a result,
/// this function is O(1) after the first invocation, and O(n) before.
///
/// ### Examples
///
/// A valid URI with only non-empty segments:
///
/// ```rust
/// use rocket::http::uri::URIBuf;
///
/// let uri = URIBuf::new("/a/b/c");
/// assert_eq!(uri.segment_count(), 3);
/// ```
///
/// A URI with empty segments:
///
/// ```rust
/// use rocket::http::uri::URIBuf;
///
/// let uri = URIBuf::new("/a/b//c/d///e");
/// assert_eq!(uri.segment_count(), 5);
/// ```
pub fn segment_count(&self) -> usize {
self.segment_count.get().unwrap_or_else(|| {
let count = self.as_uri().segments().count();
self.segment_count.set(Some(count));
count
})
}
/// Converts this URIBuf into a borrowed URI. Does not consume this URIBuf.
#[inline(always)]
pub fn as_uri(&self) -> URI {
URI::new(self.uri.as_str())
}
/// Returns the inner string of this URIBuf.
///
/// The returned string is in raw form. It contains empty segments. If you'd
/// like a string without empty segments, use `to_string` instead.
///
/// ### Example
///
/// ```rust
/// use rocket::http::uri::URIBuf;
///
/// let uri = URIBuf::new("/a/b///c/d/e//f?name=Mike#end");
/// assert_eq!(uri.as_str(), "/a/b///c/d/e//f?name=Mike#end");
/// ```
#[inline(always)]
pub fn as_str(&self) -> &str {
self.uri.as_str()
}
}
unsafe impl Sync for URIBuf { /* It's safe! */ }
impl fmt::Display for URIBuf {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.as_uri().fmt(f)
}
}
impl From<String> for URIBuf {
#[inline(always)]
fn from(uri: String) -> URIBuf {
URIBuf {
segment_count: Cell::new(None),
uri: uri,
}
}
}
impl<'a> From<&'a str> for URIBuf {
#[inline(always)]
fn from(uri: &'a str) -> URIBuf {
URIBuf {
segment_count: Cell::new(None),
uri: uri.to_string(),
}
}
}
impl<'a, 'b> Collider<URI<'b>> for URI<'a> {
fn collides_with(&self, other: &URI<'b>) -> bool {
for (seg_a, seg_b) in self.segments().zip(other.segments()) {
@ -509,12 +375,11 @@ impl<'a> Iterator for Segments<'a> {
#[cfg(test)]
mod tests {
use super::{URI, URIBuf};
use super::URI;
fn seg_count(path: &str, expected: usize) -> bool {
let actual = URI::new(path).segment_count();
let actual_buf = URIBuf::from(path).segment_count();
if actual != expected || actual_buf != expected {
if actual != expected {
trace_!("Count mismatch: expected {}, got {}.", expected, actual);
trace_!("{}", if actual != expected { "lifetime" } else { "buf" });
trace_!("Segments (for {}):", path);
@ -523,18 +388,13 @@ mod tests {
}
}
actual == expected && actual_buf == expected
actual == expected
}
fn eq_segments(path: &str, expected: &[&str]) -> bool {
let uri = URI::new(path);
let actual: Vec<&str> = uri.segments().collect();
let uri_buf = URIBuf::from(path);
let uri_buf_uri = uri_buf.as_uri();
let actual_buf: Vec<&str> = uri_buf_uri.segments().collect();
actual == expected && actual_buf == expected
actual == expected
}
#[test]

View File

@ -383,7 +383,7 @@ impl Rocket {
}
for mut route in routes {
let path = format!("{}/{}", base, route.path.as_uri());
let path = format!("{}/{}", base, route.path);
route.set_path(path);
info_!("{}", route);

View File

@ -10,7 +10,7 @@ use codegen::StaticRouteInfo;
use handler::Handler;
use request::Request;
use http::{Method, ContentType};
use http::uri::{URI, URIBuf};
use http::uri::URI;
/// A route: a method, its handler, path, rank, and format/content type.
pub struct Route {
@ -19,7 +19,7 @@ pub struct Route {
/// A function that should be called when the route matches.
pub handler: Handler,
/// The path (in Rocket format) that should be matched against.
pub path: URIBuf,
pub path: URI<'static>,
/// The rank of this route. Lower ranks have higher priorities.
pub rank: isize,
/// The Content-Type this route matches against.
@ -44,7 +44,7 @@ impl Route {
method: m,
handler: handler,
rank: default_rank(path.as_ref()),
path: URIBuf::from(path.as_ref()),
path: URI::from(path.as_ref().to_string()),
content_type: ContentType::Any,
}
}
@ -55,7 +55,7 @@ impl Route {
{
Route {
method: m,
path: URIBuf::from(path.as_ref()),
path: URI::from(path.as_ref().to_string()),
handler: handler,
rank: rank,
content_type: ContentType::Any,
@ -65,7 +65,7 @@ impl Route {
/// Sets the path of the route. Does not update the rank or any other
/// parameters.
pub fn set_path<S>(&mut self, path: S) where S: AsRef<str> {
self.path = URIBuf::from(path.as_ref());
self.path = URI::from(path.as_ref().to_string());
}
// FIXME: Decide whether a component has to be fully variable or not. That
@ -75,8 +75,7 @@ impl Route {
/// dynamic segments in this route.
#[doc(hidden)]
pub fn get_param_indexes(&self, uri: &URI) -> Vec<(usize, usize)> {
let path_uri = self.path.as_uri();
let route_segs = path_uri.segments();
let route_segs = self.path.segments();
let uri_segs = uri.segments();
let start_addr = uri.as_str().as_ptr() as usize;
@ -147,14 +146,14 @@ impl Collider for Route {
self.method == b.method
&& self.rank == b.rank
&& self.content_type.collides_with(&b.content_type)
&& self.path.as_uri().collides_with(&b.path.as_uri())
&& self.path.collides_with(&b.path)
}
}
impl<'r> Collider<Request<'r>> for Route {
fn collides_with(&self, req: &Request<'r>) -> bool {
self.method == req.method()
&& req.uri().collides_with(&self.path.as_uri())
&& req.uri().collides_with(&self.path)
&& req.content_type().collides_with(&self.content_type)
}
}