use std::fmt::{self, Debug, Display};
#[derive(PartialEq)]
pub enum Pattern {
Root,
Static(Param),
Dynamic(Param),
Wildcard(Param),
}
#[derive(Debug, PartialEq)]
pub struct Param {
ident: Box<str>,
}
pub fn patterns(path: &'static str) -> impl Iterator<Item = Pattern> {
let mut segments = vec![];
super::split(&mut segments, path);
segments.into_iter().map(|at| {
let end = at.end();
let start = at.start();
let segment = match path.get(start..end) {
Some(slice) => slice,
None => panic!("Path segments cannot be empty when defining a route."),
};
match segment.chars().next() {
Some(':') => {
let param = Param::new(match segment.get(1..) {
None | Some("") => panic!("Dynamic parameters must be named. Found ':'."),
Some(rest) => rest,
});
Pattern::Dynamic(param)
}
Some('*') => {
let param = Param::new(match segment.get(1..) {
None | Some("") => panic!("Wildcard parameters must be named. Found '*'."),
Some(rest) => rest,
});
Pattern::Wildcard(param)
}
_ => {
let param = Param::new(segment);
Pattern::Static(param)
}
}
})
}
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 {
#[inline]
fn clone(&self) -> Self {
Self {
ident: self.ident.clone(),
}
}
}
impl Display for Param {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Display::fmt(&self.ident, f)
}
}