From e1884aa5970145252ccfefc060e3a1f8eb8cc23e Mon Sep 17 00:00:00 2001 From: Landon Work Date: Sun, 30 Nov 2025 13:14:09 -0500 Subject: [PATCH 1/4] Completed abs_path new constructor for windows --- core/src/abs_path.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/core/src/abs_path.rs b/core/src/abs_path.rs index 0f31f58..587b1b9 100644 --- a/core/src/abs_path.rs +++ b/core/src/abs_path.rs @@ -305,6 +305,22 @@ impl<'a> NormalizeState<'a> { } #[inline] + #[cfg(windows)] + fn new(original_str: &'a str) -> Result { + if matches!(original_str.chars().next(), Some('a'..='z' | 'A'..='Z')) && &original_str[1..3] == ":\\" { + let cursor = 4; // e.g. "C:\\" + Ok(Self { + cursor, + normalized_path: NormalizedPath::Slice(0..cursor), + original_str, + }) + } else { + Err(NormalizeError::NotAbsolute) + } + } + + #[inline] + #[cfg(not(windows))] fn new(original_str: &'a str) -> Result { if original_str.starts_with(MAIN_SEPARATOR_STR) { let cursor = MAIN_SEPARATOR_STR.len(); From 2f89ddee2bbba5df4672934db030d8b1250c5da9 Mon Sep 17 00:00:00 2001 From: Landon Work Date: Sun, 30 Nov 2025 13:21:18 -0500 Subject: [PATCH 2/4] Fixed off by one error --- core/src/abs_path.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/abs_path.rs b/core/src/abs_path.rs index 587b1b9..8bcb72b 100644 --- a/core/src/abs_path.rs +++ b/core/src/abs_path.rs @@ -307,7 +307,7 @@ impl<'a> NormalizeState<'a> { #[inline] #[cfg(windows)] fn new(original_str: &'a str) -> Result { - if matches!(original_str.chars().next(), Some('a'..='z' | 'A'..='Z')) && &original_str[1..3] == ":\\" { + if matches!(original_str.chars().next(), Some('a'..='z' | 'A'..='Z')) && &original_str[1..4] == ":\\" { let cursor = 4; // e.g. "C:\\" Ok(Self { cursor, From 8953a8366f280b7f99c8d535507417266956e5fc Mon Sep 17 00:00:00 2001 From: Landon Work Date: Sun, 30 Nov 2025 13:22:51 -0500 Subject: [PATCH 3/4] Revert "Fixed off by one error" This reverts commit 2f89ddee2bbba5df4672934db030d8b1250c5da9. --- core/src/abs_path.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/abs_path.rs b/core/src/abs_path.rs index 8bcb72b..587b1b9 100644 --- a/core/src/abs_path.rs +++ b/core/src/abs_path.rs @@ -307,7 +307,7 @@ impl<'a> NormalizeState<'a> { #[inline] #[cfg(windows)] fn new(original_str: &'a str) -> Result { - if matches!(original_str.chars().next(), Some('a'..='z' | 'A'..='Z')) && &original_str[1..4] == ":\\" { + if matches!(original_str.chars().next(), Some('a'..='z' | 'A'..='Z')) && &original_str[1..3] == ":\\" { let cursor = 4; // e.g. "C:\\" Ok(Self { cursor, From 2da8d9021e51731c9d0769d4d389fc85029923ca Mon Sep 17 00:00:00 2001 From: Landon Work Date: Sun, 30 Nov 2025 15:44:19 -0500 Subject: [PATCH 4/4] abs_path corrections, added test --- core/src/abs_path.rs | 62 +++++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/core/src/abs_path.rs b/core/src/abs_path.rs index 587b1b9..fc4cf7c 100644 --- a/core/src/abs_path.rs +++ b/core/src/abs_path.rs @@ -109,13 +109,13 @@ impl AbsPath { // The string doesn't contain the path separator. return Err(AbsPathNotAbsoluteError); }; - if offset != 0 { - // The string doesn't start with the path separator. + + if offset != (if cfg!(windows) { 2 } else { 0 }) { return Err(AbsPathNotAbsoluteError); } let separator_len = MAIN_SEPARATOR_STR.len(); - let mut valid_up_to = separator_len; + let mut valid_up_to = separator_len + (if cfg!(windows) { 2 } else { 0 }); while let Some(offset) = separator_offsets.next() { let component = r#const::str_slice(str, valid_up_to..offset); @@ -305,32 +305,32 @@ impl<'a> NormalizeState<'a> { } #[inline] - #[cfg(windows)] fn new(original_str: &'a str) -> Result { - if matches!(original_str.chars().next(), Some('a'..='z' | 'A'..='Z')) && &original_str[1..3] == ":\\" { - let cursor = 4; // e.g. "C:\\" - Ok(Self { - cursor, - normalized_path: NormalizedPath::Slice(0..cursor), - original_str, - }) - } else { - Err(NormalizeError::NotAbsolute) + let cursor = MAIN_SEPARATOR_STR.len() + if cfg!(windows) { 2 } else { 0 }; + #[cfg(windows)] + { + if matches!(original_str.chars().next(), Some('a'..='z' | 'A'..='Z')) && original_str.get(1..cursor) == Some(":\\") { + Ok(Self { + cursor, + normalized_path: NormalizedPath::Slice(0..cursor), + original_str, + }) + } else { + Err(NormalizeError::NotAbsolute) + } } - } - #[inline] - #[cfg(not(windows))] - fn new(original_str: &'a str) -> Result { - if original_str.starts_with(MAIN_SEPARATOR_STR) { - let cursor = MAIN_SEPARATOR_STR.len(); - Ok(Self { - cursor, - normalized_path: NormalizedPath::Slice(0..cursor), - original_str, - }) - } else { - Err(NormalizeError::NotAbsolute) + #[cfg(not(windows))] + { + if original_str.starts_with(MAIN_SEPARATOR_STR) { + Ok(Self { + cursor, + normalized_path: NormalizedPath::Slice(0..cursor), + original_str, + }) + } else { + Err(NormalizeError::NotAbsolute) + } } } @@ -672,3 +672,13 @@ mod serde_impls { } } } + +#[cfg(test)] +mod tests { + use super::AbsPath; + #[cfg(windows)] + #[test] + fn test_windows_abs_path() { + assert!(AbsPath::from_str("C:\\Users\\User1").is_ok()); + } +}