diff --git a/actix-router/src/lib.rs b/actix-router/src/lib.rs index f616f7fc6..03f464626 100644 --- a/actix-router/src/lib.rs +++ b/actix-router/src/lib.rs @@ -7,144 +7,20 @@ mod de; mod path; +mod pattern; mod resource; +mod resource_path; mod router; -pub use self::de::PathDeserializer; -pub use self::path::Path; -pub use self::resource::ResourceDef; -pub use self::router::{ResourceInfo, Router, RouterBuilder}; - -// TODO: this trait is necessary, document it -// see impl Resource for ServiceRequest -pub trait Resource { - fn resource_path(&mut self) -> &mut Path; -} - -pub trait ResourcePath { - fn path(&self) -> &str; -} - -impl ResourcePath for String { - fn path(&self) -> &str { - self.as_str() - } -} - -impl<'a> ResourcePath for &'a str { - fn path(&self) -> &str { - self - } -} - -impl ResourcePath for bytestring::ByteString { - fn path(&self) -> &str { - &*self - } -} - -/// One or many patterns. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum Patterns { - Single(String), - List(Vec), -} - -impl Patterns { - pub fn is_empty(&self) -> bool { - match self { - Patterns::Single(_) => false, - Patterns::List(pats) => pats.is_empty(), - } - } -} - -/// Helper trait for type that could be converted to one or more path pattern. -pub trait IntoPatterns { - fn patterns(&self) -> Patterns; -} - -impl IntoPatterns for String { - fn patterns(&self) -> Patterns { - Patterns::Single(self.clone()) - } -} - -impl<'a> IntoPatterns for &'a String { - fn patterns(&self) -> Patterns { - Patterns::Single((*self).clone()) - } -} - -impl<'a> IntoPatterns for &'a str { - fn patterns(&self) -> Patterns { - Patterns::Single((*self).to_owned()) - } -} - -impl IntoPatterns for bytestring::ByteString { - fn patterns(&self) -> Patterns { - Patterns::Single(self.to_string()) - } -} - -impl IntoPatterns for Patterns { - fn patterns(&self) -> Patterns { - self.clone() - } -} - -impl> IntoPatterns for Vec { - fn patterns(&self) -> Patterns { - let mut patterns = self.iter().map(|v| v.as_ref().to_owned()); - - match patterns.size_hint() { - (1, _) => Patterns::Single(patterns.next().unwrap()), - _ => Patterns::List(patterns.collect()), - } - } -} - -macro_rules! array_patterns_single (($tp:ty) => { - impl IntoPatterns for [$tp; 1] { - fn patterns(&self) -> Patterns { - Patterns::Single(self[0].to_owned()) - } - } -}); - -macro_rules! array_patterns_multiple (($tp:ty, $str_fn:expr, $($num:tt) +) => { - // for each array length specified in $num - $( - impl IntoPatterns for [$tp; $num] { - fn patterns(&self) -> Patterns { - Patterns::List(self.iter().map($str_fn).collect()) - } - } - )+ -}); - -array_patterns_single!(&str); -array_patterns_multiple!(&str, |&v| v.to_owned(), 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16); - -array_patterns_single!(String); -array_patterns_multiple!(String, |v| v.clone(), 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16); - #[cfg(feature = "http")] mod url; +pub use self::de::PathDeserializer; +pub use self::path::Path; +pub use self::pattern::{IntoPatterns, Patterns}; +pub use self::resource::ResourceDef; +pub use self::resource_path::{Resource, ResourcePath}; +pub use self::router::{ResourceInfo, Router, RouterBuilder}; + #[cfg(feature = "http")] pub use self::url::{Quoter, Url}; - -#[cfg(feature = "http")] -mod http_impls { - use http::Uri; - - use super::ResourcePath; - - impl ResourcePath for Uri { - fn path(&self) -> &str { - self.path() - } - } -} diff --git a/actix-router/src/pattern.rs b/actix-router/src/pattern.rs new file mode 100644 index 000000000..78a638a78 --- /dev/null +++ b/actix-router/src/pattern.rs @@ -0,0 +1,92 @@ +/// One or many patterns. +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum Patterns { + Single(String), + List(Vec), +} + +impl Patterns { + pub fn is_empty(&self) -> bool { + match self { + Patterns::Single(_) => false, + Patterns::List(pats) => pats.is_empty(), + } + } +} + +/// Helper trait for type that could be converted to one or more path patterns. +pub trait IntoPatterns { + fn patterns(&self) -> Patterns; +} + +impl IntoPatterns for String { + fn patterns(&self) -> Patterns { + Patterns::Single(self.clone()) + } +} + +impl IntoPatterns for &String { + fn patterns(&self) -> Patterns { + (*self).patterns() + } +} + +impl IntoPatterns for str { + fn patterns(&self) -> Patterns { + Patterns::Single(self.to_owned()) + } +} + +impl IntoPatterns for &str { + fn patterns(&self) -> Patterns { + (*self).patterns() + } +} + +impl IntoPatterns for bytestring::ByteString { + fn patterns(&self) -> Patterns { + Patterns::Single(self.to_string()) + } +} + +impl IntoPatterns for Patterns { + fn patterns(&self) -> Patterns { + self.clone() + } +} + +impl> IntoPatterns for Vec { + fn patterns(&self) -> Patterns { + let mut patterns = self.iter().map(|v| v.as_ref().to_owned()); + + match patterns.size_hint() { + (1, _) => Patterns::Single(patterns.next().unwrap()), + _ => Patterns::List(patterns.collect()), + } + } +} + +macro_rules! array_patterns_single (($tp:ty) => { + impl IntoPatterns for [$tp; 1] { + fn patterns(&self) -> Patterns { + Patterns::Single(self[0].to_owned()) + } + } +}); + +macro_rules! array_patterns_multiple (($tp:ty, $str_fn:expr, $($num:tt) +) => { + // for each array length specified in space-separated $num + $( + impl IntoPatterns for [$tp; $num] { + fn patterns(&self) -> Patterns { + Patterns::List(self.iter().map($str_fn).collect()) + } + } + )+ +}); + +array_patterns_single!(&str); +array_patterns_multiple!(&str, |&v| v.to_owned(), 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16); + +array_patterns_single!(String); +array_patterns_multiple!(String, |v| v.clone(), 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16); diff --git a/actix-router/src/resource_path.rs b/actix-router/src/resource_path.rs new file mode 100644 index 000000000..91a7f2f55 --- /dev/null +++ b/actix-router/src/resource_path.rs @@ -0,0 +1,36 @@ +use crate::Path; + +// TODO: this trait is necessary, document it +// see impl Resource for ServiceRequest +pub trait Resource { + fn resource_path(&mut self) -> &mut Path; +} + +pub trait ResourcePath { + fn path(&self) -> &str; +} + +impl ResourcePath for String { + fn path(&self) -> &str { + self.as_str() + } +} + +impl<'a> ResourcePath for &'a str { + fn path(&self) -> &str { + self + } +} + +impl ResourcePath for bytestring::ByteString { + fn path(&self) -> &str { + &*self + } +} + +#[cfg(feature = "http")] +impl ResourcePath for http::Uri { + fn path(&self) -> &str { + self.path() + } +}