From 2c71f5f709fa91aa86be4ebe2fa1270c7d3b618d Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Mon, 2 Sep 2024 16:33:18 -0700 Subject: [PATCH] Adjust --- src/relative_path.rs | 43 ++++++++++++++++++++++++++++++++++++++++--- tests/create.rs | 2 +- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/relative_path.rs b/src/relative_path.rs index d8d3688..068e23d 100644 --- a/src/relative_path.rs +++ b/src/relative_path.rs @@ -10,9 +10,13 @@ pub(crate) enum Error { LeadingSlash, #[snafu(display("trailing slash"))] TrailingSlash, + #[snafu(display("Windows disk prefix `{letter}:`"))] + DiskPrefix { + letter: char, + }, #[snafu(display("double slash"))] DoubleSlash, - #[snafu(display("illegal character `{}`", character.escape_default()))] + #[snafu(display("illegal character `{character}`"))] Character { character: char, }, @@ -151,6 +155,15 @@ impl FromStr for RelativePath { return Err(Error::DoubleSlash); } + let mut chars = s.chars(); + let first = chars.next(); + let second = chars.next(); + if let Some((first, second)) = first.zip(second) { + if second == ':' { + return Err(Error::DiskPrefix { letter: first }); + } + } + let mut path = String::new(); for (i, component) in s.split('/').enumerate() { @@ -192,12 +205,25 @@ mod tests { use super::*; #[test] - fn errors() { + fn from_str() { + #[track_caller] + fn case(path: &str, expected: &str) { + assert_eq!(path.parse::().unwrap(), expected); + } + + case("foo", "foo"); + case("foo/bar", "foo/bar"); + } + + #[test] + fn from_str_errors() { #[track_caller] fn case(path: &str, expected: Error) { assert_eq!(path.parse::().unwrap_err(), expected); } + case("C:", Error::DiskPrefix { letter: 'C' }); + case("", Error::Empty); case( ".", @@ -212,11 +238,22 @@ mod tests { }, ); case("/", Error::LeadingSlash); + case("foo/", Error::TrailingSlash); + case("foo//bar", Error::DoubleSlash); case("\\", Error::Character { character: '\\' }); } #[test] - fn check_portability() { + fn portability() { + "foo" + .parse::() + .unwrap() + .check_portability() + .unwrap(); + } + + #[test] + fn portability_errors() { #[track_caller] fn case(path: &str, expected: Error) { assert_eq!( diff --git a/tests/create.rs b/tests/create.rs index 8088aa1..a8229e5 100644 --- a/tests/create.rs +++ b/tests/create.rs @@ -141,7 +141,7 @@ fn backslash_error() { "error: invalid path `\\` because: -- illegal character `\\\\` +- illegal character `\\` ", ) .failure();