about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2015-03-31 11:26:10 -0700
committerAlex Crichton <alex@alexcrichton.com>2015-03-31 15:53:26 -0700
commitda04788efca6ec1e421139fb4916a5aacd49a2e2 (patch)
tree91bb44f384c9927d40392696e9b356fd22b77bd5 /src/libstd
parent94137a37e90f2fc5faf725965b419944e14ad271 (diff)
parent9fc51efe3344a32d9e522f08383f052277b6ab63 (diff)
downloadrust-da04788efca6ec1e421139fb4916a5aacd49a2e2.tar.gz
rust-da04788efca6ec1e421139fb4916a5aacd49a2e2.zip
rollup merge of #23875: aturon/revise-convert-2
* Marks `#[stable]` the contents of the `std::convert` module.

* Added methods `PathBuf::as_path`, `OsString::as_os_str`,
  `String::as_str`, `Vec::{as_slice, as_mut_slice}`.

* Deprecates `OsStr::from_str` in favor of a new, stable, and more
  general `OsStr::new`.

* Adds unstable methods `OsString::from_bytes` and `OsStr::{to_bytes,
  to_cstring}` for ergonomic FFI usage.

[breaking-change]

r? @alexcrichton
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/dynamic_lib.rs1
-rw-r--r--src/libstd/env.rs1
-rw-r--r--src/libstd/ffi/os_str.rs85
-rw-r--r--src/libstd/lib.rs3
-rw-r--r--src/libstd/path.rs15
-rw-r--r--src/libstd/sys/unix/ext.rs9
-rw-r--r--src/libstd/sys/unix/fs2.rs4
-rw-r--r--src/libstd/sys/unix/process2.rs2
8 files changed, 92 insertions, 28 deletions
diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs
index d8a95133d94..f9bb7e6cbd4 100644
--- a/src/libstd/dynamic_lib.rs
+++ b/src/libstd/dynamic_lib.rs
@@ -190,7 +190,6 @@ mod dl {
     use ffi::{CStr, OsStr};
     use str;
     use libc;
-    use os::unix::prelude::*;
     use ptr;
 
     pub fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> {
diff --git a/src/libstd/env.rs b/src/libstd/env.rs
index c50548081ab..5abe0f7a0b6 100644
--- a/src/libstd/env.rs
+++ b/src/libstd/env.rs
@@ -340,7 +340,6 @@ pub struct JoinPathsError {
 /// # Examples
 ///
 /// ```
-/// # #![feature(convert)]
 /// use std::env;
 /// use std::path::PathBuf;
 ///
diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs
index 49dbac4585b..30e96ec465f 100644
--- a/src/libstd/ffi/os_str.rs
+++ b/src/libstd/ffi/os_str.rs
@@ -35,6 +35,7 @@
 use core::prelude::*;
 
 use borrow::{Borrow, Cow, ToOwned};
+use ffi::CString;
 use fmt::{self, Debug};
 use mem;
 use string::String;
@@ -42,6 +43,7 @@ use ops;
 use cmp;
 use hash::{Hash, Hasher};
 use old_path::{Path, GenericPath};
+use vec::Vec;
 
 use sys::os_str::{Buf, Slice};
 use sys_common::{AsInner, IntoInner, FromInner};
@@ -83,6 +85,37 @@ impl OsString {
         OsString { inner: Buf::from_string(String::new()) }
     }
 
+    /// Construct an `OsString` from a byte sequence.
+    ///
+    /// # Platform behavior
+    ///
+    /// On Unix systems, any byte sequence can be successfully
+    /// converted into an `OsString`.
+    ///
+    /// On Windows system, only UTF-8 byte sequences will successfully
+    /// convert; non UTF-8 data will produce `None`.
+    #[unstable(feature = "convert", reason = "recently added")]
+    pub fn from_bytes<B>(bytes: B) -> Option<OsString> where B: Into<Vec<u8>> {
+        #[cfg(unix)]
+        fn from_bytes_inner(vec: Vec<u8>) -> Option<OsString> {
+            use os::unix::ffi::OsStringExt;
+            Some(OsString::from_vec(vec))
+        }
+
+        #[cfg(windows)]
+        fn from_bytes_inner(vec: Vec<u8>) -> Option<OsString> {
+            String::from_utf8(vec).ok().map(OsString::from)
+        }
+
+        from_bytes_inner(bytes.into())
+    }
+
+    /// Convert to an `OsStr` slice.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn as_os_str(&self) -> &OsStr {
+        self
+    }
+
     /// Convert the `OsString` into a `String` if it contains valid Unicode data.
     ///
     /// On failure, ownership of the original `OsString` is returned.
@@ -211,8 +244,16 @@ impl Hash for OsString {
 }
 
 impl OsStr {
+    /// Coerce into an `OsStr` slice.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &OsStr {
+        s.as_ref()
+    }
+
     /// Coerce directly from a `&str` slice to a `&OsStr` slice.
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[deprecated(since = "1.0.0",
+                 reason = "use `OsStr::new` instead")]
     pub fn from_str(s: &str) -> &OsStr {
         unsafe { mem::transmute(Slice::from_str(s)) }
     }
@@ -239,6 +280,36 @@ impl OsStr {
         OsString { inner: self.inner.to_owned() }
     }
 
+    /// Yield this `OsStr` as a byte slice.
+    ///
+    /// # Platform behavior
+    ///
+    /// On Unix systems, this is a no-op.
+    ///
+    /// On Windows systems, this returns `None` unless the `OsStr` is
+    /// valid unicode, in which case it produces UTF-8-encoded
+    /// data. This may entail checking validity.
+    #[unstable(feature = "convert", reason = "recently added")]
+    pub fn to_bytes(&self) -> Option<&[u8]> {
+        if cfg!(windows) {
+            self.to_str().map(|s| s.as_bytes())
+        } else {
+            Some(self.bytes())
+        }
+    }
+
+    /// Create a `CString` containing this `OsStr` data.
+    ///
+    /// Fails if the `OsStr` contains interior nulls.
+    ///
+    /// This is a convenience for creating a `CString` from
+    /// `self.to_bytes()`, and inherits the platform behavior of the
+    /// `to_bytes` method.
+    #[unstable(feature = "convert", reason = "recently added")]
+    pub fn to_cstring(&self) -> Option<CString> {
+        self.to_bytes().and_then(|b| CString::new(b).ok())
+    }
+
     /// Get the underlying byte representation.
     ///
     /// Note: it is *crucial* that this API is private, to avoid
@@ -258,14 +329,14 @@ impl PartialEq for OsStr {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl PartialEq<str> for OsStr {
     fn eq(&self, other: &str) -> bool {
-        *self == *OsStr::from_str(other)
+        *self == *OsStr::new(other)
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl PartialEq<OsStr> for str {
     fn eq(&self, other: &OsStr) -> bool {
-        *other == *OsStr::from_str(self)
+        *other == *OsStr::new(self)
     }
 }
 
@@ -292,7 +363,7 @@ impl PartialOrd for OsStr {
 impl PartialOrd<str> for OsStr {
     #[inline]
     fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
-        self.partial_cmp(OsStr::from_str(other))
+        self.partial_cmp(OsStr::new(other))
     }
 }
 
@@ -359,7 +430,7 @@ impl AsOsStr for OsString {
 #[deprecated(since = "1.0.0", reason = "trait is deprecated")]
 impl AsOsStr for str {
     fn as_os_str(&self) -> &OsStr {
-        OsStr::from_str(self)
+        unsafe { mem::transmute(Slice::from_str(self)) }
     }
 }
 
@@ -367,7 +438,7 @@ impl AsOsStr for str {
 #[deprecated(since = "1.0.0", reason = "trait is deprecated")]
 impl AsOsStr for String {
     fn as_os_str(&self) -> &OsStr {
-        OsStr::from_str(&self[..])
+        unsafe { mem::transmute(Slice::from_str(self)) }
     }
 }
 
@@ -388,14 +459,14 @@ impl AsRef<OsStr> for OsString {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl AsRef<OsStr> for str {
     fn as_ref(&self) -> &OsStr {
-        OsStr::from_str(self)
+        unsafe { mem::transmute(Slice::from_str(self)) }
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl AsRef<OsStr> for String {
     fn as_ref(&self) -> &OsStr {
-        OsStr::from_str(&self[..])
+        unsafe { mem::transmute(Slice::from_str(self)) }
     }
 }
 
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index a17be591811..6b21dbc2f09 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -122,12 +122,11 @@
 #![feature(unsafe_no_drop_flag, filling_drop)]
 #![feature(macro_reexport)]
 #![feature(unique)]
-#![feature(convert)]
 #![feature(allow_internal_unstable)]
 #![feature(str_char)]
 #![feature(into_cow)]
-#![feature(slice_patterns)]
 #![feature(std_misc)]
+#![feature(slice_patterns)]
 #![feature(debug_builders)]
 #![cfg_attr(test, feature(test, rustc_private, std_misc))]
 
diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index 58d3ae9f7cf..36a5d1465f0 100644
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -35,7 +35,6 @@
 //! To build or modify paths, use `PathBuf`:
 //!
 //! ```rust
-//! # #![feature(convert)]
 //! use std::path::PathBuf;
 //!
 //! let mut path = PathBuf::from("c:\\");
@@ -521,9 +520,9 @@ impl<'a> Component<'a> {
     pub fn as_os_str(self) -> &'a OsStr {
         match self {
             Component::Prefix(p) => p.as_os_str(),
-            Component::RootDir => OsStr::from_str(MAIN_SEP_STR),
-            Component::CurDir => OsStr::from_str("."),
-            Component::ParentDir => OsStr::from_str(".."),
+            Component::RootDir => OsStr::new(MAIN_SEP_STR),
+            Component::CurDir => OsStr::new("."),
+            Component::ParentDir => OsStr::new(".."),
             Component::Normal(path) => path,
         }
     }
@@ -893,7 +892,6 @@ impl<'a> cmp::Ord for Components<'a> {
 /// # Examples
 ///
 /// ```
-/// # #![feature(convert)]
 /// use std::path::PathBuf;
 ///
 /// let mut path = PathBuf::from("c:\\");
@@ -918,6 +916,12 @@ impl PathBuf {
         PathBuf { inner: OsString::new() }
     }
 
+    /// Coerce to a `Path` slice.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn as_path(&self) -> &Path {
+        self
+    }
+
     /// Extend `self` with `path`.
     ///
     /// If `path` is absolute, it replaces the current path.
@@ -985,7 +989,6 @@ impl PathBuf {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(convert)]
     /// use std::path::PathBuf;
     ///
     /// let mut buf = PathBuf::from("/");
diff --git a/src/libstd/sys/unix/ext.rs b/src/libstd/sys/unix/ext.rs
index 080cf5620fc..fbfbb40701f 100644
--- a/src/libstd/sys/unix/ext.rs
+++ b/src/libstd/sys/unix/ext.rs
@@ -207,7 +207,7 @@ pub mod io {
 /// Unix-specific extension to the primitives in the `std::ffi` module
 #[stable(feature = "rust1", since = "1.0.0")]
 pub mod ffi {
-    use ffi::{CString, NulError, OsStr, OsString};
+    use ffi::{OsStr, OsString};
     use mem;
     use prelude::v1::*;
     use sys::os_str::Buf;
@@ -244,10 +244,6 @@ pub mod ffi {
         /// Get the underlying byte view of the `OsStr` slice.
         #[stable(feature = "rust1", since = "1.0.0")]
         fn as_bytes(&self) -> &[u8];
-
-        /// Convert the `OsStr` slice into a `CString`.
-        #[stable(feature = "rust1", since = "1.0.0")]
-        fn to_cstring(&self) -> Result<CString, NulError>;
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -258,9 +254,6 @@ pub mod ffi {
         fn as_bytes(&self) -> &[u8] {
             &self.as_inner().inner
         }
-        fn to_cstring(&self) -> Result<CString, NulError> {
-            CString::new(self.as_bytes())
-        }
     }
 }
 
diff --git a/src/libstd/sys/unix/fs2.rs b/src/libstd/sys/unix/fs2.rs
index 80fc1235a31..c5d3dce2634 100644
--- a/src/libstd/sys/unix/fs2.rs
+++ b/src/libstd/sys/unix/fs2.rs
@@ -276,8 +276,8 @@ impl File {
 }
 
 fn cstr(path: &Path) -> io::Result<CString> {
-    let cstring = try!(path.as_os_str().to_cstring());
-    Ok(cstring)
+    path.as_os_str().to_cstring().ok_or(
+        io::Error::new(io::ErrorKind::InvalidInput, "path contained a null", None))
 }
 
 impl FromInner<c_int> for File {
diff --git a/src/libstd/sys/unix/process2.rs b/src/libstd/sys/unix/process2.rs
index 20c409154b8..c2a8b26aef4 100644
--- a/src/libstd/sys/unix/process2.rs
+++ b/src/libstd/sys/unix/process2.rs
@@ -54,7 +54,7 @@ impl Command {
         self.args.push(arg.to_cstring().unwrap())
     }
     pub fn args<'a, I: Iterator<Item = &'a OsStr>>(&mut self, args: I) {
-        self.args.extend(args.map(|s| OsStrExt::to_cstring(s).unwrap()))
+        self.args.extend(args.map(|s| s.to_cstring().unwrap()))
     }
     fn init_env_map(&mut self) {
         if self.env.is_none() {