|
2 | 2 | //! `Components` and `DirectoryPackage` are the two sides of the
|
3 | 3 | //! installation / uninstallation process.
|
4 | 4 |
|
| 5 | +use std::borrow::Cow; |
5 | 6 | use std::io::BufWriter;
|
6 | 7 | use std::path::{Path, PathBuf};
|
7 | 8 |
|
@@ -148,12 +149,28 @@ impl<'a> ComponentBuilder<'a> {
|
148 | 149 | pub struct ComponentPart(pub String, pub PathBuf);
|
149 | 150 |
|
150 | 151 | impl ComponentPart {
|
| 152 | + const PATH_SEP_MANIFEST: &str = "/"; |
| 153 | + const PATH_SEP_MAIN: &str = std::path::MAIN_SEPARATOR_STR; |
| 154 | + |
151 | 155 | pub(crate) fn encode(&self) -> String {
|
152 |
| - format!("{}:{}", &self.0, &self.1.to_string_lossy()) |
| 156 | + // Lossy conversion is safe here because we assume that `path` comes from |
| 157 | + // `ComponentPart::decode()`, i.e. from calling `Path::from()` on a `&str`. |
| 158 | + let mut path = self.1.to_string_lossy(); |
| 159 | + if Self::PATH_SEP_MAIN != Self::PATH_SEP_MANIFEST { |
| 160 | + path = Cow::Owned(path.replace(Self::PATH_SEP_MAIN, Self::PATH_SEP_MANIFEST)); |
| 161 | + }; |
| 162 | + format!("{}:{path}", self.0) |
153 | 163 | }
|
| 164 | + |
154 | 165 | pub(crate) fn decode(line: &str) -> Option<Self> {
|
155 |
| - line.find(':') |
156 |
| - .map(|pos| Self(line[0..pos].to_owned(), PathBuf::from(&line[(pos + 1)..]))) |
| 166 | + line.find(':').map(|pos| { |
| 167 | + let mut path_str = Cow::Borrowed(&line[(pos + 1)..]); |
| 168 | + if Self::PATH_SEP_MANIFEST != Self::PATH_SEP_MAIN { |
| 169 | + path_str = |
| 170 | + Cow::Owned(path_str.replace(Self::PATH_SEP_MANIFEST, Self::PATH_SEP_MAIN)); |
| 171 | + }; |
| 172 | + Self(line[0..pos].to_owned(), PathBuf::from(path_str.as_ref())) |
| 173 | + }) |
157 | 174 | }
|
158 | 175 | }
|
159 | 176 |
|
@@ -322,3 +339,27 @@ impl Component {
|
322 | 339 | Ok(tx)
|
323 | 340 | }
|
324 | 341 | }
|
| 342 | + |
| 343 | +#[cfg(test)] |
| 344 | +mod tests { |
| 345 | + use super::*; |
| 346 | + |
| 347 | + #[test] |
| 348 | + fn decode_component_part() { |
| 349 | + let ComponentPart(kind, path) = ComponentPart::decode("dir:share/doc/rust/html").unwrap(); |
| 350 | + assert_eq!(kind, "dir"); |
| 351 | + assert_eq!( |
| 352 | + path, |
| 353 | + Path::new(&"share/doc/rust/html".replace("/", ComponentPart::PATH_SEP_MAIN)) |
| 354 | + ); |
| 355 | + } |
| 356 | + |
| 357 | + #[test] |
| 358 | + fn encode_component_part() { |
| 359 | + let part = ComponentPart( |
| 360 | + "dir".to_owned(), |
| 361 | + ["share", "doc", "rust", "html"].into_iter().collect(), |
| 362 | + ); |
| 363 | + assert_eq!(part.encode(), "dir:share/doc/rust/html"); |
| 364 | + } |
| 365 | +} |
0 commit comments