Skip to content

Commit 599a840

Browse files
committed
add tests
1 parent 22ffd2f commit 599a840

File tree

2 files changed

+92
-42
lines changed

2 files changed

+92
-42
lines changed

crates/core/src/blob/tree.rs

Lines changed: 1 addition & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use std::{
2-
borrow::Cow,
32
cmp::Ordering,
43
collections::{BTreeMap, BTreeSet, BinaryHeap},
54
mem,
@@ -13,7 +12,7 @@ use ignore::overrides::{Override, OverrideBuilder};
1312
use ignore::Match;
1413
use serde::{Deserialize, Deserializer};
1514
use serde_derive::Serialize;
16-
use typed_path::{Component, TypedPath, UnixPath, UnixPathBuf, WindowsComponent, WindowsPrefix};
15+
use typed_path::{Component, UnixPath, UnixPathBuf};
1716

1817
use crate::{
1918
backend::{
@@ -396,45 +395,6 @@ pub struct FindMatches {
396395
pub matches: Vec<Vec<(usize, usize)>>,
397396
}
398397

399-
/// Converts a [`TypedPath`] to an [`Cow<UnixPath>`].
400-
///
401-
/// # Arguments
402-
///
403-
/// * `p` - The component to convert.
404-
///
405-
/// # Errors
406-
///
407-
/// * If the component is a current or parent directory.
408-
/// * If the component is not UTF-8 conform.
409-
pub(crate) fn typed_path_to_unix_path<'a>(p: &'a TypedPath<'_>) -> Cow<'a, UnixPath> {
410-
match p {
411-
TypedPath::Unix(path) => Cow::Borrowed(path),
412-
TypedPath::Windows(path) => {
413-
let mut unix_path = UnixPathBuf::new();
414-
for c in path.with_windows_encoding().components() {
415-
match c {
416-
WindowsComponent::Prefix(p) => match p.kind() {
417-
WindowsPrefix::Verbatim(p) | WindowsPrefix::DeviceNS(p) => {
418-
unix_path.push(p);
419-
}
420-
WindowsPrefix::VerbatimUNC(_, q) | WindowsPrefix::UNC(_, q) => {
421-
unix_path.push(q);
422-
}
423-
WindowsPrefix::VerbatimDisk(p) | WindowsPrefix::Disk(p) => {
424-
let c = vec![p];
425-
unix_path.push(&c);
426-
}
427-
},
428-
c => {
429-
unix_path.push(c);
430-
}
431-
}
432-
}
433-
Cow::Owned(unix_path)
434-
}
435-
}
436-
}
437-
438398
impl IntoIterator for Tree {
439399
type Item = Node;
440400
type IntoIter = std::vec::IntoIter<Node>;

crates/core/src/util.rs

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
/// Utilities for handling paths on ``rustic_core``
2+
use std::borrow::Cow;
3+
24
use globset::GlobMatcher;
35
use serde::{Serialize, Serializer};
4-
use typed_path::{UnixPath, UnixPathBuf};
6+
use typed_path::{
7+
Component, TypedPath, UnixComponent, UnixPath, UnixPathBuf, WindowsComponent, WindowsPath,
8+
WindowsPrefix,
9+
};
510

611
/// Extend `globset::GlobMatcher` to allow mathing on unix paths (on every platform)
712
pub trait GlobMatcherExt {
@@ -43,3 +48,88 @@ where
4348
let s = format!("{}", path.display());
4449
serializer.serialize_str(&s)
4550
}
51+
52+
/// Converts a [`TypedPath`] to an [`Cow<UnixPath>`].
53+
///
54+
/// # Arguments
55+
///
56+
/// * `path` - The path to convert.
57+
#[must_use]
58+
pub fn typed_path_to_unix_path<'a>(path: &'a TypedPath<'_>) -> Cow<'a, UnixPath> {
59+
match path {
60+
TypedPath::Unix(p) => Cow::Borrowed(p),
61+
TypedPath::Windows(p) => Cow::Owned(windows_path_to_unix_path(p)),
62+
}
63+
}
64+
65+
/// Converts a [`WindowsPath`] to a [`UnixPathBuf`].
66+
///
67+
/// # Arguments
68+
///
69+
/// * `path` - The path to convert.
70+
#[must_use]
71+
pub fn windows_path_to_unix_path(path: &WindowsPath) -> UnixPathBuf {
72+
let mut unix_path = UnixPathBuf::new();
73+
let mut components = path.components();
74+
if let Some(c) = components.next() {
75+
match c {
76+
WindowsComponent::Prefix(p) => {
77+
unix_path.push(UnixComponent::RootDir);
78+
match p.kind() {
79+
WindowsPrefix::Verbatim(p) | WindowsPrefix::DeviceNS(p) => {
80+
unix_path.push(p);
81+
}
82+
WindowsPrefix::VerbatimUNC(_, q) | WindowsPrefix::UNC(_, q) => {
83+
unix_path.push(q);
84+
}
85+
WindowsPrefix::VerbatimDisk(p) | WindowsPrefix::Disk(p) => {
86+
let c = vec![p];
87+
unix_path.push(&c);
88+
}
89+
}
90+
// remove RootDir from iterator
91+
_ = components.next();
92+
}
93+
WindowsComponent::RootDir => {
94+
unix_path.push(UnixComponent::RootDir);
95+
}
96+
c => {
97+
unix_path.push(c.as_bytes());
98+
}
99+
}
100+
}
101+
for c in components {
102+
match c {
103+
WindowsComponent::RootDir => {
104+
unix_path.push(UnixComponent::RootDir);
105+
}
106+
c => {
107+
unix_path.push(c);
108+
}
109+
}
110+
}
111+
unix_path
112+
}
113+
114+
#[cfg(test)]
115+
mod tests {
116+
use super::*;
117+
use rstest::rstest;
118+
#[rstest]
119+
#[case("/", "/")]
120+
#[case(r#"\"#, "/")]
121+
#[case("/test/test2", "/test/test2")]
122+
#[case(r#"\test\test2"#, "/test/test2")]
123+
#[case(r#"C:\"#, "/C")]
124+
#[case(r#"C:\dir"#, "/C/dir")]
125+
#[case(r#"a\b\"#, "a/b")]
126+
#[case(r#"a\b\c"#, "a/b/c")]
127+
fn test_typed_path_to_unix_path(#[case] windows_path: &str, #[case] unix_path: &str) {
128+
assert_eq!(
129+
windows_path_to_unix_path(WindowsPath::new(windows_path))
130+
.to_str()
131+
.unwrap(),
132+
UnixPath::new(unix_path).to_str().unwrap()
133+
);
134+
}
135+
}

0 commit comments

Comments
 (0)