Skip to content

Commit

Permalink
Add skeleton of expander, with tests
Browse files Browse the repository at this point in the history
  • Loading branch information
CathalMullan committed Sep 8, 2024
1 parent 6d2929a commit 32ee790
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 3 deletions.
64 changes: 64 additions & 0 deletions src/expander.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
use crate::parser::{ParsedRoute, RoutePart};

/// Represents a collection of expanded, simplified routes, derived from an original route.
#[derive(Debug, PartialEq, Eq)]
pub struct ExpandedRoutes {
pub original: ParsedRoute,
pub routes: Vec<ParsedRoute>,
}

impl ExpandedRoutes {
pub fn new(route: ParsedRoute) -> Self {
let routes = vec![];

Self {
original: route,
routes,
}
}
}

#[cfg(test)]
mod tests {
use super::*;
use std::error::Error;

#[test]
fn test_expand_users_route() -> Result<(), Box<dyn Error>> {
let route = ParsedRoute::new(b"/users/{id?}")?;
let expanded = ExpandedRoutes::new(route.clone());

assert_eq!(
expanded,
ExpandedRoutes {
original: route,
routes: vec![
ParsedRoute::new(b"/users")?,
ParsedRoute::new(b"/users/{id}")?,
]
}
);

Ok(())
}

#[test]
fn test_expand_release_route() -> Result<(), Box<dyn Error>> {
let route = ParsedRoute::new(b"/release/v{major}.{minor?}.{patch?}")?;
let expanded = ExpandedRoutes::new(route.clone());

assert_eq!(
expanded,
ExpandedRoutes {
original: route,
routes: vec![
ParsedRoute::new(b"/release/v{major}")?,
ParsedRoute::new(b"/release/v{major}.{minor}")?,
ParsedRoute::new(b"/release/v{major}.{minor}.{patch}")?,
]
}
);

Ok(())
}
}
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ pub(crate) mod decode;

pub mod errors;

pub(crate) mod expander;

pub(crate) mod node;
pub use node::search::{Match, Parameter};

Expand Down
52 changes: 49 additions & 3 deletions src/parser.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use crate::errors::RouteError;
use std::fmt::Debug;
use std::fmt::{self, Debug};

/// Characters that are not allowed in parameter names or constraints.
const INVALID_PARAM_CHARS: [u8; 6] = [b':', b'*', b'?', b'{', b'}', b'/'];

/// A parsed section of a route.
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Clone, PartialEq, Eq)]
pub enum RoutePart {
Static {
prefix: Vec<u8>,
Expand All @@ -24,8 +24,45 @@ pub enum RoutePart {
},
}

impl Debug for RoutePart {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Static { prefix } => f
.debug_struct("Dynamic")
.field("prefix", &String::from_utf8_lossy(prefix))
.finish(),
Self::Dynamic {
name,
optional,
constraint,
} => f
.debug_struct("Dynamic")
.field("name", &String::from_utf8_lossy(name))
.field("optional", optional)
.field(
"constraint",
&constraint.as_ref().map(|c| String::from_utf8_lossy(c)),
)
.finish(),
Self::Wildcard {
name,
optional,
constraint,
} => f
.debug_struct("Wildcard")
.field("name", &String::from_utf8_lossy(name))
.field("optional", optional)
.field(
"constraint",
&constraint.as_ref().map(|c| String::from_utf8_lossy(c)),
)
.finish(),
}
}
}

/// A parsed route.
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Clone, PartialEq, Eq)]
pub struct ParsedRoute {
/// The original route.
pub route: Vec<u8>,
Expand Down Expand Up @@ -230,6 +267,15 @@ impl<'a> IntoIterator for &'a ParsedRoute {
}
}

impl Debug for ParsedRoute {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("ParsedRoute")
.field("route", &String::from_utf8_lossy(&self.route))
.field("parts", &self.parts)
.finish()
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down

0 comments on commit 32ee790

Please sign in to comment.