diff --git a/arbiter-core/src/lib.rs b/arbiter-core/src/lib.rs index 84a835d..cdf8b17 100644 --- a/arbiter-core/src/lib.rs +++ b/arbiter-core/src/lib.rs @@ -18,3 +18,46 @@ pub mod presence; pub mod signet; pub mod filter; + +pub fn normalize_windows_path(path: &str) -> String { + fn is_drive_root(p: &str) -> bool { + let b = p.as_bytes(); + b.len() == 3 && b[1] == b':' && b[2] == b'\\' + } + let mut out = path.trim().replace('/', "\\"); + + while out.ends_with('\\') && !is_drive_root(&out) { + out.pop(); + } + out +} + +#[cfg(test)] +mod test { + use super::normalize_windows_path; + + #[test] + fn removes_trailing_slash() { + assert_eq!( + normalize_windows_path(r"C\:temp\folder\"), + r"C\:temp\folder" + ); + } + + #[test] + fn preserve_drive_root() { + assert_eq!(normalize_windows_path(r"C:\"), r"C:\"); + } + #[test] + fn normalizes_forward_slashes() { + assert_eq!(normalize_windows_path("C:/temp/test/ "), r"C:\temp\test"); + } + #[test] + fn trim_whitespace() { + assert_eq!(normalize_windows_path(" C:/temp/test/ "), r"C:\temp\test"); + } + #[test] + fn preserve_drive_root_after_normalization() { + assert_eq!(normalize_windows_path("C:/"), r"C:\"); + } +} diff --git a/arbiter-forge/src/main.rs b/arbiter-forge/src/main.rs index f9e0b86..2789331 100644 --- a/arbiter-forge/src/main.rs +++ b/arbiter-forge/src/main.rs @@ -13,6 +13,7 @@ use arbiter_core::decree::{ Action, ActionType, DecreeId, DecreeNode, NodeId, NodeKind, PresenceConfig, }; use arbiter_core::ledger::SummonsDef; +use arbiter_core::normalize_windows_path; use arbiter_core::protocol::ForgeCommand; thread_local! { @@ -54,19 +55,6 @@ fn generate_step_id() -> String { format!("step-{epoch}-{n}") } -fn normalize_windows_path(path: &str) -> String { - fn is_drive_root(p: &str) -> bool { - let b = p.as_bytes(); - b.len() == 3 && b[1] == b':' && b[2] == b'\\' - } - - let mut out = path.trim().replace('/', "\\"); - while out.ends_with('\\') && !is_drive_root(&out) { - out.pop(); - } - out -} - fn collect_decree_from_ui(ui: &ArbiterForge) -> arbiter_core::ledger::DecreeDef { let label = ui.get_active_decree_label().to_string(); let id_str = ui.get_active_decree_id().to_string();