use std::fmt::{self, Debug, Display};
use std::sync::Arc;
use super::SplitPath;
#[derive(PartialEq)]
pub enum Pattern {
Root,
Static(Param),
Dynamic(Param),
CatchAll(Param),
}
#[derive(Debug, PartialEq)]
pub struct Param {
ident: Arc<str>,
}
pub fn patterns(path: &'static str) -> impl Iterator<Item = Pattern> {
SplitPath::new(path).map(|at| {
let segment = path.get(at.start()..at.end()).unwrap_or("");
match segment.chars().next() {
Some(':') => {
let rest = segment.get(1..).unwrap_or("");
Pattern::Dynamic(Param::new(rest))
}
Some('*') => {
let rest = segment.get(1..).unwrap_or("");
Pattern::CatchAll(Param::new(rest))
}
_ => {
Pattern::Static(Param::new(segment))
}
}
})
}
impl Param {
pub fn as_str(&self) -> &str {
&self.ident
}
}
impl Param {
pub(crate) fn new(ident: &str) -> Self {
Self {
ident: ident.into(),
}
}
}
impl Clone for Param {
fn clone(&self) -> Self {
Self {
ident: Arc::clone(&self.ident),
}
}
}
impl Display for Param {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Display::fmt(&self.ident, f)
}
}