From 560944b982385623655f1e8503af5e7b4ca0a436 Mon Sep 17 00:00:00 2001 From: Clar Charr Date: Mon, 13 Feb 2017 20:37:42 -0500 Subject: [PATCH] Add From> implementations. --- src/libcollections/string.rs | 16 +++++++++++++++ src/libcollections/vec.rs | 16 +++++++++++++++ src/libstd/ffi/c_str.rs | 33 ++++++++++++++++++++++++------- src/libstd/ffi/os_str.rs | 34 +++++++++++++++++++++++++------- src/libstd/path.rs | 34 +++++++++++++++++++++++++------- src/libstd/sys/redox/os_str.rs | 6 ++++++ src/libstd/sys/unix/os_str.rs | 6 ++++++ src/libstd/sys/windows/os_str.rs | 6 ++++++ src/libstd/sys_common/wtf8.rs | 6 ++++++ 9 files changed, 136 insertions(+), 21 deletions(-) diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 43323676ab459..13c99a2d59bed 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -1974,6 +1974,22 @@ impl<'a> From<&'a str> for String { } } +// note: test pulls in libstd, which causes errors here +#[cfg(not(test))] +#[stable(feature = "string_from_box", since = "1.17.0")] +impl From> for String { + fn from(s: Box) -> String { + s.into_string() + } +} + +#[stable(feature = "box_from_str", since = "1.17.0")] +impl Into> for String { + fn into(self) -> Box { + self.into_boxed_str() + } +} + #[stable(feature = "string_from_cow_str", since = "1.14.0")] impl<'a> From> for String { fn from(s: Cow<'a, str>) -> String { diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index d38c9f6e1cf80..e4a6af33409e1 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1897,6 +1897,22 @@ impl<'a, T> From> for Vec where [T]: ToOwned> { } } +// note: test pulls in libstd, which causes errors here +#[cfg(not(test))] +#[stable(feature = "vec_from_box", since = "1.17.0")] +impl From> for Vec { + fn from(s: Box<[T]>) -> Vec { + s.into_vec() + } +} + +#[stable(feature = "box_from_vec", since = "1.17.0")] +impl Into> for Vec { + fn into(self) -> Box<[T]> { + self.into_boxed_slice() + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl<'a> From<&'a str> for Vec { fn from(s: &'a str) -> Vec { diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index bc678fcb8385b..a3f4154ba4af7 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -304,7 +304,7 @@ impl CString { } /// Converts this `CString` into a boxed `CStr`. - #[unstable(feature = "into_boxed_c_str", issue = "0")] + #[unstable(feature = "into_boxed_c_str", issue = "40380")] pub fn into_boxed_c_str(self) -> Box { unsafe { mem::transmute(self.into_inner()) } } @@ -394,6 +394,20 @@ impl<'a> From<&'a CStr> for Box { } } +#[stable(feature = "c_string_from_box", since = "1.17.0")] +impl From> for CString { + fn from(s: Box) -> CString { + s.into_c_string() + } +} + +#[stable(feature = "box_from_c_string", since = "1.17.0")] +impl Into> for CString { + fn into(self) -> Box { + self.into_boxed_c_str() + } +} + #[stable(feature = "default_box_extra", since = "1.17.0")] impl Default for Box { fn default() -> Box { @@ -694,6 +708,12 @@ impl CStr { pub fn to_string_lossy(&self) -> Cow { String::from_utf8_lossy(self.to_bytes()) } + + /// Converts a `Box` into a `CString` without copying or allocating. + #[unstable(feature = "into_boxed_c_str", issue = "40380")] + pub fn into_c_string(self: Box) -> CString { + unsafe { mem::transmute(self) } + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -888,12 +908,11 @@ mod tests { fn into_boxed() { let orig: &[u8] = b"Hello, world!\0"; let cstr = CStr::from_bytes_with_nul(orig).unwrap(); - let cstring = cstr.to_owned(); - let box1: Box = Box::from(cstr); - let box2 = cstring.into_boxed_c_str(); - assert_eq!(cstr, &*box1); - assert_eq!(box1, box2); - assert_eq!(&*box2, cstr); + let boxed: Box = Box::from(cstr); + let cstring = cstr.to_owned().into_boxed_c_str().into_c_string(); + assert_eq!(cstr, &*boxed); + assert_eq!(&*boxed, &*cstring); + assert_eq!(&*cstring, cstr); } #[test] diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index 7b8bf42e0a74a..c9c207d8b8eb4 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -206,7 +206,7 @@ impl OsString { } /// Converts this `OsString` into a boxed `OsStr`. - #[unstable(feature = "into_boxed_os_str", issue = "0")] + #[unstable(feature = "into_boxed_os_str", issue = "40380")] pub fn into_boxed_os_str(self) -> Box { unsafe { mem::transmute(self.inner.into_box()) } } @@ -442,6 +442,13 @@ impl OsStr { self.inner.inner.len() } + /// Converts a `Box` into an `OsString` without copying or allocating. + #[unstable(feature = "into_boxed_os_str", issue = "40380")] + pub fn into_os_string(self: Box) -> OsString { + let inner: Box = unsafe { mem::transmute(self) }; + OsString { inner: Buf::from_box(inner) } + } + /// Gets the underlying byte representation. /// /// Note: it is *crucial* that this API is private, to avoid @@ -458,6 +465,20 @@ impl<'a> From<&'a OsStr> for Box { } } +#[stable(feature = "os_string_from_box", since = "1.17.0")] +impl<'a> From> for OsString { + fn from(boxed: Box) -> OsString { + boxed.into_os_string() + } +} + +#[stable(feature = "box_from_c_string", since = "1.17.0")] +impl Into> for OsString { + fn into(self) -> Box { + self.into_boxed_os_str() + } +} + #[stable(feature = "box_default_extra", since = "1.17.0")] impl Default for Box { fn default() -> Box { @@ -766,12 +787,11 @@ mod tests { fn into_boxed() { let orig = "Hello, world!"; let os_str = OsStr::new(orig); - let os_string = os_str.to_owned(); - let box1: Box = Box::from(os_str); - let box2 = os_string.into_boxed_os_str(); - assert_eq!(os_str, &*box1); - assert_eq!(box1, box2); - assert_eq!(&*box2, os_str); + let boxed: Box = Box::from(os_str); + let os_string = os_str.to_owned().into_boxed_os_str().into_os_string(); + assert_eq!(os_str, &*boxed); + assert_eq!(&*boxed, &*os_string); + assert_eq!(&*os_string, os_str); } #[test] diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 245a6d945b5a3..49b01bc085373 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -1196,7 +1196,7 @@ impl PathBuf { } /// Converts this `PathBuf` into a boxed `Path`. - #[unstable(feature = "into_boxed_path", issue = "0")] + #[unstable(feature = "into_boxed_path", issue = "40380")] pub fn into_boxed_path(self) -> Box { unsafe { mem::transmute(self.inner.into_boxed_os_str()) } } @@ -1210,6 +1210,20 @@ impl<'a> From<&'a Path> for Box { } } +#[stable(feature = "path_buf_from_box", since = "1.17.0")] +impl<'a> From> for PathBuf { + fn from(boxed: Box) -> PathBuf { + boxed.into_path_buf() + } +} + +#[stable(feature = "box_from_path_buf", since = "1.17.0")] +impl Into> for PathBuf { + fn into(self) -> Box { + self.into_boxed_path() + } +} + #[stable(feature = "box_default_extra", since = "1.17.0")] impl Default for Box { fn default() -> Box { @@ -2089,6 +2103,13 @@ impl Path { pub fn is_dir(&self) -> bool { fs::metadata(self).map(|m| m.is_dir()).unwrap_or(false) } + + /// Converts a `Box` into a `PathBuf` without copying or allocating. + #[unstable(feature = "into_boxed_path", issue = "40380")] + pub fn into_path_buf(self: Box) -> PathBuf { + let inner: Box = unsafe { mem::transmute(self) }; + PathBuf { inner: OsString::from(inner) } + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -3703,12 +3724,11 @@ mod tests { fn into_boxed() { let orig: &str = "some/sort/of/path"; let path = Path::new(orig); - let path_buf = path.to_owned(); - let box1: Box = Box::from(path); - let box2 = path_buf.into_boxed_path(); - assert_eq!(path, &*box1); - assert_eq!(box1, box2); - assert_eq!(&*box2, path); + let boxed: Box = Box::from(path); + let path_buf = path.to_owned().into_boxed_path().into_path_buf(); + assert_eq!(path, &*boxed); + assert_eq!(&*boxed, &*path_buf); + assert_eq!(&*path_buf, path); } #[test] diff --git a/src/libstd/sys/redox/os_str.rs b/src/libstd/sys/redox/os_str.rs index 0f967863899cb..90b8289524e26 100644 --- a/src/libstd/sys/redox/os_str.rs +++ b/src/libstd/sys/redox/os_str.rs @@ -99,6 +99,12 @@ impl Buf { pub fn into_box(self) -> Box { unsafe { mem::transmute(self.inner.into_boxed_slice()) } } + + #[inline] + pub fn from_box(boxed: Box) -> Buf { + let inner: Box<[u8]> = unsafe { mem::transmute(boxed) }; + Buf { inner: inner.into_vec() } + } } impl Slice { diff --git a/src/libstd/sys/unix/os_str.rs b/src/libstd/sys/unix/os_str.rs index 938bcfc6d162e..225924168a5b2 100644 --- a/src/libstd/sys/unix/os_str.rs +++ b/src/libstd/sys/unix/os_str.rs @@ -99,6 +99,12 @@ impl Buf { pub fn into_box(self) -> Box { unsafe { mem::transmute(self.inner.into_boxed_slice()) } } + + #[inline] + pub fn from_box(boxed: Box) -> Buf { + let inner: Box<[u8]> = unsafe { mem::transmute(boxed) }; + Buf { inner: inner.into_vec() } + } } impl Slice { diff --git a/src/libstd/sys/windows/os_str.rs b/src/libstd/sys/windows/os_str.rs index 04e45dcf54963..810b67b785b5c 100644 --- a/src/libstd/sys/windows/os_str.rs +++ b/src/libstd/sys/windows/os_str.rs @@ -93,6 +93,12 @@ impl Buf { pub fn into_box(self) -> Box { unsafe { mem::transmute(self.inner.into_box()) } } + + #[inline] + pub fn from_box(boxed: Box) -> Buf { + let inner: Box = unsafe { mem::transmute(boxed) }; + Buf { inner: Wtf8Buf::from_box(inner) } + } } impl Slice { diff --git a/src/libstd/sys_common/wtf8.rs b/src/libstd/sys_common/wtf8.rs index 1d61181a4ee0f..28cab10e8f9cc 100644 --- a/src/libstd/sys_common/wtf8.rs +++ b/src/libstd/sys_common/wtf8.rs @@ -346,6 +346,12 @@ impl Wtf8Buf { pub fn into_box(self) -> Box { unsafe { mem::transmute(self.bytes.into_boxed_slice()) } } + + /// Converts a `Box` into a `Wtf8Buf`. + pub fn from_box(boxed: Box) -> Wtf8Buf { + let bytes: Box<[u8]> = unsafe { mem::transmute(boxed) }; + Wtf8Buf { bytes: bytes.into_vec() } + } } /// Create a new WTF-8 string from an iterator of code points.