Skip to content

Commit

Permalink
fix(component): normalize path separators during `ComponentPart::(en|…
Browse files Browse the repository at this point in the history
…de)code()`
  • Loading branch information
rami3l committed Feb 10, 2025
1 parent 2298aa5 commit c412a54
Showing 1 changed file with 44 additions and 3 deletions.
47 changes: 44 additions & 3 deletions src/dist/component/components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//! `Components` and `DirectoryPackage` are the two sides of the
//! installation / uninstallation process.
use std::borrow::Cow;
use std::io::BufWriter;
use std::path::{Path, PathBuf};

Expand Down Expand Up @@ -148,12 +149,28 @@ impl<'a> ComponentBuilder<'a> {
pub struct ComponentPart(pub String, pub PathBuf);

impl ComponentPart {
const PATH_SEP_MANIFEST: &str = "/";
const PATH_SEP_MAIN: &str = std::path::MAIN_SEPARATOR_STR;

pub(crate) fn encode(&self) -> String {
format!("{}:{}", &self.0, &self.1.to_string_lossy())
let mut path = self.1.to_string_lossy();
if Self::PATH_SEP_MAIN != Self::PATH_SEP_MANIFEST {
// Lossy conversion is safe here because we assume that `path` comes from
// `ComponentPart::decode()`, i.e. from calling `Path::from()` on a `&str`.
path = Cow::Owned(path.replace(Self::PATH_SEP_MAIN, Self::PATH_SEP_MANIFEST));
};
format!("{}:{path}", self.0)
}

pub(crate) fn decode(line: &str) -> Option<Self> {
line.find(':')
.map(|pos| Self(line[0..pos].to_owned(), PathBuf::from(&line[(pos + 1)..])))
line.find(':').map(|pos| {
let mut path_str = Cow::Borrowed(&line[(pos + 1)..]);
if Self::PATH_SEP_MANIFEST != Self::PATH_SEP_MAIN {
path_str =
Cow::Owned(path_str.replace(Self::PATH_SEP_MANIFEST, Self::PATH_SEP_MAIN));
};
Self(line[0..pos].to_owned(), PathBuf::from(path_str.as_ref()))
})
}
}

Expand Down Expand Up @@ -322,3 +339,27 @@ impl Component {
Ok(tx)
}
}

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

#[test]
fn decode_component_part() {
let ComponentPart(kind, path) = ComponentPart::decode("dir:share/doc/rust/html").unwrap();
assert_eq!(kind, "dir");
assert_eq!(
path,
Path::new(&"share/doc/rust/html".replace("/", ComponentPart::PATH_SEP_MAIN))
);
}

#[test]
fn encode_component_part() {
let part = ComponentPart(
"dir".to_owned(),
["share", "doc", "rust", "html"].into_iter().collect(),
);
assert_eq!(part.encode(), "dir:share/doc/rust/html");
}
}

0 comments on commit c412a54

Please sign in to comment.