From 1dfe5088d85df13a172810d0df92c25dbcc37e98 Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Thu, 26 Sep 2013 00:54:30 -0700 Subject: [PATCH] path2: Add opt variants for from_vec/from_str --- src/libstd/path2/mod.rs | 23 +++++++++++++++++++++++ src/libstd/path2/posix.rs | 20 ++++++++++++++++++++ src/libstd/path2/windows.rs | 30 ++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+) diff --git a/src/libstd/path2/mod.rs b/src/libstd/path2/mod.rs index 183086a785be..054a8a36eb5f 100644 --- a/src/libstd/path2/mod.rs +++ b/src/libstd/path2/mod.rs @@ -81,6 +81,17 @@ pub trait GenericPath: Clone + GenericPathUnsafe { } } + /// Creates a new Path from a byte vector, if possible. + /// The resulting Path will always be normalized. + #[inline] + fn from_vec_opt(path: &[u8]) -> Option { + if contains_nul(path) { + None + } else { + Some(unsafe { GenericPathUnsafe::from_vec_unchecked(path) }) + } + } + /// Creates a new Path from a string. /// The resulting Path will always be normalized. /// @@ -97,6 +108,18 @@ pub trait GenericPath: Clone + GenericPathUnsafe { } } + /// Creates a new Path from a string, if possible. + /// The resulting Path will always be normalized. + #[inline] + fn from_str_opt(path: &str) -> Option { + let v = path.as_bytes(); + if contains_nul(v) { + None + } else { + Some(unsafe { GenericPathUnsafe::from_str_unchecked(path) }) + } + } + /// Creates a new Path from a CString. /// The resulting Path will always be normalized. /// diff --git a/src/libstd/path2/posix.rs b/src/libstd/path2/posix.rs index 66b4a6fb3267..fb39be7b6b17 100644 --- a/src/libstd/path2/posix.rs +++ b/src/libstd/path2/posix.rs @@ -287,6 +287,12 @@ impl Path { GenericPath::from_vec(v) } + /// Returns a new Path from a byte vector, if possible + #[inline] + pub fn from_vec_opt(v: &[u8]) -> Option { + GenericPath::from_vec_opt(v) + } + /// Returns a new Path from a string /// /// # Failure @@ -297,6 +303,12 @@ impl Path { GenericPath::from_str(s) } + /// Returns a new Path from a string, if possible + #[inline] + pub fn from_str_opt(s: &str) -> Option { + GenericPath::from_str_opt(s) + } + /// Converts the Path into an owned byte vector pub fn into_vec(self) -> ~[u8] { self.repr @@ -475,6 +487,14 @@ mod tests { assert_eq!(Path::from_vec(b!("foo", 0xff, "/bar")).into_str(), None); } + #[test] + fn test_opt_paths() { + assert_eq!(Path::from_vec_opt(b!("foo/bar", 0)), None); + t!(v: Path::from_vec_opt(b!("foo/bar")).unwrap(), b!("foo/bar")); + assert_eq!(Path::from_str_opt("foo/bar\0"), None); + t!(s: Path::from_str_opt("foo/bar").unwrap(), "foo/bar"); + } + #[test] fn test_null_byte() { use path2::null_byte::cond; diff --git a/src/libstd/path2/windows.rs b/src/libstd/path2/windows.rs index e4c194ba6cae..747f803f08ce 100644 --- a/src/libstd/path2/windows.rs +++ b/src/libstd/path2/windows.rs @@ -328,6 +328,15 @@ impl GenericPathUnsafe for Path { } impl GenericPath for Path { + #[inline] + fn from_vec_opt(v: &[u8]) -> Option { + if contains_nul(v) || !str::is_utf8(v) { + None + } else { + Some(unsafe { GenericPathUnsafe::from_vec_unchecked(v) }) + } + } + /// See `GenericPath::as_str` for info. /// Always returns a `Some` value. #[inline] @@ -583,6 +592,12 @@ impl Path { GenericPath::from_vec(v) } + /// Returns a new Path from a byte vector, if possible + #[inline] + pub fn from_vec_opt(v: &[u8]) -> Option { + GenericPath::from_vec_opt(v) + } + /// Returns a new Path from a string /// /// # Failure @@ -593,6 +608,12 @@ impl Path { GenericPath::from_str(s) } + /// Returns a new Path from a string, if possible + #[inline] + pub fn from_str_opt(s: &str) -> Option { + GenericPath::from_str_opt(s) + } + /// Converts the Path into an owned byte vector pub fn into_vec(self) -> ~[u8] { self.repr.into_bytes() @@ -1201,6 +1222,15 @@ mod tests { t!(s: Path::from_str("\\\\.\\foo\\bar"), "\\\\.\\foo\\bar"); } + #[test] + fn test_opt_paths() { + assert_eq!(Path::from_vec_opt(b!("foo\\bar", 0)), None); + assert_eq!(Path::from_vec_opt(b!("foo\\bar", 0x80)), None); + t!(v: Path::from_vec_opt(b!("foo\\bar")).unwrap(), b!("foo\\bar")); + assert_eq!(Path::from_str_opt("foo\\bar\0"), None); + t!(s: Path::from_str_opt("foo\\bar").unwrap(), "foo\\bar"); + } + #[test] fn test_null_byte() { use path2::null_byte::cond;