Skip to content

Commit

Permalink
Add invalid parameter/constraint names to errors
Browse files Browse the repository at this point in the history
  • Loading branch information
CathalMullan committed Aug 27, 2024
1 parent ac4c2fe commit d4e0a34
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 42 deletions.
82 changes: 46 additions & 36 deletions src/errors/route.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ pub enum RouteError {
EmptyBraces {
/// The path containing empty braces.
path: String,
/// The position where the empty braces were found.
/// The position of the empty brace.
position: usize,
},

/// An unescaped brace was found in the path.
///
/// # Examples
///
/// ```
/// ```rust
/// use wayfind::errors::RouteError;
///
/// let error = RouteError::UnescapedBrace {
Expand All @@ -58,7 +58,7 @@ pub enum RouteError {
/// assert_eq!(error.to_string(), display.trim());
/// ```
UnescapedBrace {
/// The path constaining an unescaped brace.
/// The path containing an unescaped brace.
path: String,
/// The position of the unescaped brace.
position: usize,
Expand All @@ -68,7 +68,7 @@ pub enum RouteError {
///
/// # Examples
///
/// ```
/// ```rust
/// use wayfind::errors::RouteError;
///
/// let error = RouteError::EmptyParameter {
Expand All @@ -87,23 +87,24 @@ pub enum RouteError {
/// assert_eq!(error.to_string(), display.trim());
/// ```
EmptyParameter {
/// The path constaining an empty parameter.
/// The path containing an empty parameter.
path: String,
/// The position of the empty parameter.
/// The position of the parameter with a empty name.
start: usize,
/// The length of the empty parameter (including braces).
/// The length of the parameter (including braces).
length: usize,
},

/// An invalid parameter name was found in the path.
///
/// # Examples
///
/// ```
/// ```rust
/// use wayfind::errors::RouteError;
///
/// let error = RouteError::InvalidParameter {
/// path: "/{a/b}".to_string(),
/// name: "a/b".to_string(),
/// start: 1,
/// length: 5,
/// };
Expand All @@ -120,19 +121,21 @@ pub enum RouteError {
/// assert_eq!(error.to_string(), display.trim());
/// ```
InvalidParameter {
/// The path constaining an invalid parameter.
/// The path containing an invalid parameter.
path: String,
/// The position of the invalid parameter.
/// The invalid parameter name.
name: String,
/// The position of the parameter with a invalid name.
start: usize,
/// The length of the invalid parameter (including braces).
/// The length of the parameter (including braces).
length: usize,
},

/// An empty wildcard parameter was found in the path.
/// A wildcard parameter with no name was found in the path.
///
/// # Examples
///
/// ```
/// ```rust
/// use wayfind::errors::RouteError;
///
/// let error = RouteError::EmptyWildcard {
Expand All @@ -151,72 +154,78 @@ pub enum RouteError {
/// assert_eq!(error.to_string(), display.trim());
/// ```
EmptyWildcard {
/// The path constaining an empty wildcard parameter.
/// The path containing an empty wildcard parameter.
path: String,
/// The position of the empty wildcard parameter.
/// The position of the wildcard parameter with a empty name.
start: usize,
/// The length of the empty wildcard parameter (including braces).
/// The length of the parameter (including braces).
length: usize,
},

/// An empty constraint name was found in the path.
///
/// # Examples
///
/// ```
/// ```rust
/// use wayfind::errors::RouteError;
///
/// let error = RouteError::EmptyConstraint {
/// path: "/{a:}".to_string(),
/// position: 3,
/// start: 1,
/// length: 4,
/// };
///
/// let display = "
/// empty constraint name
///
/// Path: /{a:}
/// ^
/// ^^^^
/// ";
///
/// assert_eq!(error.to_string(), display.trim());
/// ```
EmptyConstraint {
/// The path constaining an empty constraint.
/// The path containing an empty constraint.
path: String,
/// The position of the empty constraint delimiter (i.e. ':').
position: usize,
/// The position of the parameter with an empty constraint.
start: usize,
/// The length of the parameter (including braces).
length: usize,
},

/// An invalid constraint name was found in the path.
///
/// # Examples
///
/// ```
/// ```rust
/// use wayfind::errors::RouteError;
///
/// let error = RouteError::InvalidConstraint {
/// path: "/{a:b/c}".to_string(),
/// start: 4,
/// length: 3,
/// name: "b/c".to_string(),
/// start: 1,
/// length: 7,
/// };
///
/// let display = "
/// invalid constraint name
///
/// Path: /{a:b/c}
/// ^^^
/// ^^^^^^^
///
/// tip: Constraint names must not contain the characters: ':', '*', '?', '{', '}', '/'
/// ";
///
/// assert_eq!(error.to_string(), display.trim());
/// ```
InvalidConstraint {
/// The path constaining an invalid constraint.
/// The path containing an invalid constraint.
path: String,
/// The position of the invalid constraint.
/// The invalid constraint name.
name: String,
/// The position of the parameter with an invalid constraint.
start: usize,
/// The length of the invalid constraint.
/// The length of the parameter (including braces).
length: usize,
},
}
Expand All @@ -228,7 +237,6 @@ impl Display for RouteError {
match self {
Self::EmptyPath => write!(f, "empty path"),

// Braces
Self::EmptyBraces { path, position } => {
let arrow = " ".repeat(*position) + "^^";
write!(
Expand All @@ -240,7 +248,6 @@ impl Display for RouteError {
)
}

// Escaping
Self::UnescapedBrace { path, position } => {
let arrow = " ".repeat(*position) + "^";
write!(
Expand All @@ -254,7 +261,6 @@ tip: Use '{{{{' and '}}}}' to represent literal '{{' and '}}' characters in the
)
}

// Parameter
Self::EmptyParameter {
path,
start,
Expand All @@ -274,6 +280,7 @@ tip: Use '{{{{' and '}}}}' to represent literal '{{' and '}}' characters in the
path,
start,
length,
..
} => {
let arrow = " ".repeat(*start) + &"^".repeat(*length);
write!(
Expand All @@ -287,7 +294,6 @@ tip: Parameter names must not contain the characters: ':', '*', '?', '{{', '}}',
)
}

// Wildcard
Self::EmptyWildcard {
path,
start,
Expand All @@ -303,9 +309,12 @@ tip: Parameter names must not contain the characters: ':', '*', '?', '{{', '}}',
)
}

// Constraint
Self::EmptyConstraint { path, position } => {
let arrow = " ".repeat(*position) + "^";
Self::EmptyConstraint {
path,
start,
length,
} => {
let arrow = " ".repeat(*start) + &"^".repeat(*length);
write!(
f,
r#"empty constraint name
Expand All @@ -319,6 +328,7 @@ tip: Parameter names must not contain the characters: ':', '*', '?', '{{', '}}',
path,
start,
length,
..
} => {
let arrow = " ".repeat(*start) + &"^".repeat(*length);
write!(
Expand Down
15 changes: 9 additions & 6 deletions src/parts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ impl<'a> Parts<'a> {
return Err(RouteError::EmptyWildcard {
path: String::from_utf8_lossy(path).to_string(),
start: cursor,
length: end - cursor + 1,
length: end - start + 2,
});
}

Expand All @@ -132,6 +132,7 @@ impl<'a> Parts<'a> {
if name.iter().any(|&c| INVALID_PARAM_CHARS.contains(&c)) {
return Err(RouteError::InvalidParameter {
path: String::from_utf8_lossy(path).to_string(),
name: String::from_utf8_lossy(name).to_string(),
start: start - 1,
length: end - start + 2,
});
Expand All @@ -141,15 +142,17 @@ impl<'a> Parts<'a> {
if constraint.is_empty() {
return Err(RouteError::EmptyConstraint {
path: String::from_utf8_lossy(path).to_string(),
position: colon.unwrap() + 2,
start: start - 1,
length: end - start + 2,
});
}

if constraint.iter().any(|&c| INVALID_PARAM_CHARS.contains(&c)) {
return Err(RouteError::InvalidConstraint {
path: String::from_utf8_lossy(path).to_string(),
start: colon.unwrap() + 3,
length: constraint.len(),
name: String::from_utf8_lossy(constraint).to_string(),
start: start - 1,
length: end - start + 2,
});
}
}
Expand Down Expand Up @@ -378,7 +381,7 @@ mod tests {
empty constraint name
Path: /{name:}
^
^^^^^^^
"###);
}

Expand Down Expand Up @@ -419,7 +422,7 @@ mod tests {
invalid constraint name
Path: /{name:with:colon}
^^^^^^^^^^
^^^^^^^^^^^^^^^^^
tip: Constraint names must not contain the characters: ':', '*', '?', '{', '}', '/'
"###);
Expand Down

0 comments on commit d4e0a34

Please sign in to comment.