Skip to content

Commit

Permalink
Merge branch 'cowext-to-slash'
Browse files Browse the repository at this point in the history
  • Loading branch information
rhysd committed Aug 6, 2022
2 parents b501224 + 9ec227c commit 7b2634f
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 8 deletions.
18 changes: 14 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,14 @@ fn example_path_ext() {
// Trait for extending std::path::Path
use path_slash::PathExt as _;

let p = Path::from_slash("foo/bar/piyo.txt");

// On Windows
assert_eq!(
Path::new(r"foo\bar\piyo.txt").to_slash().unwrap(),
"foo/bar/piyo.txt",
);
assert_eq!(p, Path::new(r"foo\bar\piyo.txt"));

// Convert to slash path
assert_eq!(p.to_slash().unwrap(), "foo/bar/piyo.txt");
assert_eq!(p.to_slash_lossy(), "foo/bar/piyo.txt");
}

fn example_pathbuf_ext() {
Expand All @@ -57,7 +60,10 @@ fn example_pathbuf_ext() {
// On Windows
let p = PathBuf::from_slash("foo/bar/piyo.txt");
assert_eq!(p, PathBuf::from(r"foo\bar\piyo.txt"));

// Convert to slash path
assert_eq!(p.to_slash().unwrap(), "foo/bar/piyo.txt");
assert_eq!(p.to_slash_lossy(), "foo/bar/piyo.txt");
}

fn example_cow_ext() {
Expand All @@ -69,6 +75,10 @@ fn example_cow_ext() {
assert_eq!(p, Cow::Owned(PathBuf::from(r"foo\bar\piyo.txt")));
// On non-Windows
assert_eq!(p, Cow::Borrowed(Path::new("foo/bar/piyo.txt")));

// Convert to slash path
assert_eq!(p.to_slash().unwrap(), "foo/bar/piyo.txt");
assert_eq!(p.to_slash_lossy(), "foo/bar/piyo.txt");
}
```

Expand Down
58 changes: 54 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,10 @@
//! assert_eq!(p, PathBuf::from(r"foo\bar\piyo.txt"));
//! assert_eq!(p.to_slash().unwrap(), "foo/bar/piyo.txt");
//!
//! // Convert to Cow<'_, Path>
//! // Convert to/from Cow<'_, Path>
//! let p = Cow::from_slash("foo/bar/piyo.txt");
//! assert_eq!(p, Cow::<Path>::Owned(PathBuf::from(r"foo\bar\piyo.txt")));
//! assert_eq!(p.to_slash().unwrap(), "foo/bar/piyo.txt");
//! }
//!
//! #[cfg(not(target_os = "windows"))]
Expand All @@ -55,9 +56,10 @@
//! assert_eq!(p, PathBuf::from("foo/bar/piyo.txt"));
//! assert_eq!(p.to_slash().unwrap(), "foo/bar/piyo.txt");
//!
//! // Convert to Cow<'_, Path>
//! // Convert to/from Cow<'_, Path>
//! let p = Cow::from_slash("foo/bar/piyo.txt");
//! assert_eq!(p, Cow::Borrowed(Path::new("foo/bar/piyo.txt")));
//! assert_eq!(p.to_slash().unwrap(), "foo/bar/piyo.txt");
//! }
//! ```
#![forbid(unsafe_code)]
Expand Down Expand Up @@ -389,9 +391,8 @@ impl PathBufExt for PathBuf {
/// Trait to extend [`Cow`].
///
/// ```
/// # use std::path::Path;
/// # use std::borrow::Cow;
/// use path_slash::{CowExt as _, PathExt as _};
/// use path_slash::CowExt as _;
///
/// assert_eq!(
/// Cow::from_slash("foo/bar/piyo.txt").to_slash_lossy(),
Expand Down Expand Up @@ -460,6 +461,47 @@ pub trait CowExt<'a> {
/// Any '\\' in the slash path is replaced with the file path separator. Heap allocation may
/// only happen on non-Windows.
fn from_backslash_lossy(s: &'a OsStr) -> Self;
/// Convert the file path into slash path as UTF-8 string. This method is similar to
/// [`Path::to_str`], but the path separator is fixed to '/'.
///
/// Any file path separators in the file path are replaced with '/'. Only when the replacement
/// happens, heap allocation happens and `Cow::Owned` is returned.
/// When the path contains non-Unicode sequences, this method returns `None`.
///
/// ```
/// # use std::path::Path;
/// # use std::borrow::Cow;
/// use path_slash::CowExt;
///
/// #[cfg(target_os = "windows")]
/// let s = Cow::Borrowed(Path::new(r"foo\bar\piyo.txt"));
///
/// #[cfg(not(target_os = "windows"))]
/// let s = Cow::Borrowed(Path::new("foo/bar/piyo.txt"));
///
/// assert_eq!(s.to_slash(), Some(Cow::Borrowed("foo/bar/piyo.txt")));
/// ```
fn to_slash(&self) -> Option<Cow<'_, str>>;
/// Convert the file path into slash path as UTF-8 string. This method is similar to
/// [`Path::to_string_lossy`], but the path separator is fixed to '/'.
///
/// Any file path separators in the file path are replaced with '/'.
/// Any non-Unicode sequences are replaced with U+FFFD.
///
/// ```
/// # use std::path::Path;
/// # use std::borrow::Cow;
/// use path_slash::CowExt;
///
/// #[cfg(target_os = "windows")]
/// let s = Cow::Borrowed(Path::new(r"foo\bar\piyo.txt"));
///
/// #[cfg(not(target_os = "windows"))]
/// let s = Cow::Borrowed(Path::new("foo/bar/piyo.txt"));
///
/// assert_eq!(s.to_slash_lossy(), "foo/bar/piyo.txt");
/// ```
fn to_slash_lossy(&self) -> Cow<'_, str>;
}

impl<'a> CowExt<'a> for Cow<'a, Path> {
Expand Down Expand Up @@ -504,4 +546,12 @@ impl<'a> CowExt<'a> for Cow<'a, Path> {
fn from_backslash_lossy(s: &'a OsStr) -> Self {
Cow::Borrowed(Path::new(s))
}

fn to_slash(&self) -> Option<Cow<'_, str>> {
self.as_ref().to_slash()
}

fn to_slash_lossy(&self) -> Cow<'_, str> {
self.as_ref().to_slash_lossy()
}
}
17 changes: 17 additions & 0 deletions tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,16 @@ fn to_slash_pathbuf() {
}
}

#[test]
fn to_slash_cow() {
for (input, expected) in TO_SLASH_TESTS.iter() {
assert_eq!(
Cow::Borrowed(input.as_path()).to_slash(),
Some(Cow::Borrowed(expected.as_str()))
);
}
}

#[test]
fn to_slash_lossy_path() {
for (input, expected) in TO_SLASH_TESTS.iter() {
Expand All @@ -180,6 +190,13 @@ fn to_slash_lossy_pathbuf() {
}
}

#[test]
fn to_slash_lossy_cow() {
for (input, expected) in TO_SLASH_TESTS.iter() {
assert_eq!(&Cow::Borrowed(input.as_path()).to_slash_lossy(), expected);
}
}

#[test]
fn from_slash_to_slash() {
for (_, path) in TO_SLASH_TESTS.iter() {
Expand Down

0 comments on commit 7b2634f

Please sign in to comment.