1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 use borrow
::{Borrow, Cow, ToOwned}
;
13 use fmt
::{self, Debug}
;
18 use hash
::{Hash, Hasher}
;
21 use sys
::os_str
::{Buf, Slice}
;
22 use sys_common
::{AsInner, IntoInner, FromInner}
;
24 /// A type that can represent owned, mutable platform-native strings, but is
25 /// cheaply interconvertable with Rust strings.
27 /// The need for this type arises from the fact that:
29 /// * On Unix systems, strings are often arbitrary sequences of non-zero
30 /// bytes, in many cases interpreted as UTF-8.
32 /// * On Windows, strings are often arbitrary sequences of non-zero 16-bit
33 /// values, interpreted as UTF-16 when it is valid to do so.
35 /// * In Rust, strings are always valid UTF-8, but may contain zeros.
37 /// `OsString` and `OsStr` bridge this gap by simultaneously representing Rust
38 /// and platform-native string values, and in particular allowing a Rust string
39 /// to be converted into an "OS" string with no cost.
41 #[stable(feature = "rust1", since = "1.0.0")]
46 /// Slices into OS strings (see `OsString`).
47 #[stable(feature = "rust1", since = "1.0.0")]
53 /// Constructs a new empty `OsString`.
54 #[stable(feature = "rust1", since = "1.0.0")]
55 pub fn new() -> OsString
{
56 OsString { inner: Buf::from_string(String::new()) }
59 /// Constructs an `OsString` from a byte sequence.
61 /// # Platform behavior
63 /// On Unix systems, any byte sequence can be successfully
64 /// converted into an `OsString`.
66 /// On Windows system, only UTF-8 byte sequences will successfully
67 /// convert; non UTF-8 data will produce `None`.
68 #[unstable(feature = "convert", reason = "recently added", issue = "27704")]
69 #[rustc_deprecated(reason = "RFC was closed, hides subtle Windows semantics",
71 pub fn from_bytes
<B
>(bytes
: B
) -> Option
<OsString
> where B
: Into
<Vec
<u8>> {
72 Self::_from_bytes(bytes
.into())
76 fn _from_bytes(vec
: Vec
<u8>) -> Option
<OsString
> {
77 use os
::unix
::ffi
::OsStringExt
;
78 Some(OsString
::from_vec(vec
))
82 fn _from_bytes(vec
: Vec
<u8>) -> Option
<OsString
> {
83 String
::from_utf8(vec
).ok().map(OsString
::from
)
86 /// Converts to an `OsStr` slice.
87 #[stable(feature = "rust1", since = "1.0.0")]
88 pub fn as_os_str(&self) -> &OsStr
{
92 /// Converts the `OsString` into a `String` if it contains valid Unicode data.
94 /// On failure, ownership of the original `OsString` is returned.
95 #[stable(feature = "rust1", since = "1.0.0")]
96 pub fn into_string(self) -> Result
<String
, OsString
> {
97 self.inner
.into_string().map_err(|buf
| OsString { inner: buf}
)
100 /// Extends the string with the given `&OsStr` slice.
101 #[stable(feature = "rust1", since = "1.0.0")]
102 pub fn push
<T
: AsRef
<OsStr
>>(&mut self, s
: T
) {
103 self.inner
.push_slice(&s
.as_ref().inner
)
107 #[stable(feature = "rust1", since = "1.0.0")]
108 impl From
<String
> for OsString
{
109 fn from(s
: String
) -> OsString
{
110 OsString { inner: Buf::from_string(s) }
114 #[stable(feature = "rust1", since = "1.0.0")]
115 impl<'a
, T
: ?Sized
+ AsRef
<OsStr
>> From
<&'a T
> for OsString
{
116 fn from(s
: &'a T
) -> OsString
{
117 s
.as_ref().to_os_string()
121 #[stable(feature = "rust1", since = "1.0.0")]
122 impl ops
::Index
<ops
::RangeFull
> for OsString
{
126 fn index(&self, _index
: ops
::RangeFull
) -> &OsStr
{
127 OsStr
::from_inner(self.inner
.as_slice())
131 #[stable(feature = "rust1", since = "1.0.0")]
132 impl ops
::Deref
for OsString
{
136 fn deref(&self) -> &OsStr
{
141 #[stable(feature = "rust1", since = "1.0.0")]
142 impl Debug
for OsString
{
143 fn fmt(&self, formatter
: &mut fmt
::Formatter
) -> Result
<(), fmt
::Error
> {
144 fmt
::Debug
::fmt(&**self, formatter
)
148 #[stable(feature = "rust1", since = "1.0.0")]
149 impl PartialEq
for OsString
{
150 fn eq(&self, other
: &OsString
) -> bool
{
155 #[stable(feature = "rust1", since = "1.0.0")]
156 impl PartialEq
<str> for OsString
{
157 fn eq(&self, other
: &str) -> bool
{
162 #[stable(feature = "rust1", since = "1.0.0")]
163 impl PartialEq
<OsString
> for str {
164 fn eq(&self, other
: &OsString
) -> bool
{
169 #[stable(feature = "rust1", since = "1.0.0")]
170 impl Eq
for OsString {}
172 #[stable(feature = "rust1", since = "1.0.0")]
173 impl PartialOrd
for OsString
{
175 fn partial_cmp(&self, other
: &OsString
) -> Option
<cmp
::Ordering
> {
176 (&**self).partial_cmp(&**other
)
179 fn lt(&self, other
: &OsString
) -> bool { &**self < &**other }
181 fn le(&self, other
: &OsString
) -> bool { &**self <= &**other }
183 fn gt(&self, other
: &OsString
) -> bool { &**self > &**other }
185 fn ge(&self, other
: &OsString
) -> bool { &**self >= &**other }
188 #[stable(feature = "rust1", since = "1.0.0")]
189 impl PartialOrd
<str> for OsString
{
191 fn partial_cmp(&self, other
: &str) -> Option
<cmp
::Ordering
> {
192 (&**self).partial_cmp(other
)
196 #[stable(feature = "rust1", since = "1.0.0")]
197 impl Ord
for OsString
{
199 fn cmp(&self, other
: &OsString
) -> cmp
::Ordering
{
200 (&**self).cmp(&**other
)
204 #[stable(feature = "rust1", since = "1.0.0")]
205 impl Hash
for OsString
{
207 fn hash
<H
: Hasher
>(&self, state
: &mut H
) {
208 (&**self).hash(state
)
213 /// Coerces into an `OsStr` slice.
214 #[stable(feature = "rust1", since = "1.0.0")]
215 pub fn new
<S
: AsRef
<OsStr
> + ?Sized
>(s
: &S
) -> &OsStr
{
219 fn from_inner(inner
: &Slice
) -> &OsStr
{
220 unsafe { mem::transmute(inner) }
223 /// Yields a `&str` slice if the `OsStr` is valid unicode.
225 /// This conversion may entail doing a check for UTF-8 validity.
226 #[stable(feature = "rust1", since = "1.0.0")]
227 pub fn to_str(&self) -> Option
<&str> {
231 /// Converts an `OsStr` to a `Cow<str>`.
233 /// Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER.
234 #[stable(feature = "rust1", since = "1.0.0")]
235 pub fn to_string_lossy(&self) -> Cow
<str> {
236 self.inner
.to_string_lossy()
239 /// Copies the slice into an owned `OsString`.
240 #[stable(feature = "rust1", since = "1.0.0")]
241 pub fn to_os_string(&self) -> OsString
{
242 OsString { inner: self.inner.to_owned() }
245 /// Yields this `OsStr` as a byte slice.
247 /// # Platform behavior
249 /// On Unix systems, this is a no-op.
251 /// On Windows systems, this returns `None` unless the `OsStr` is
252 /// valid unicode, in which case it produces UTF-8-encoded
253 /// data. This may entail checking validity.
254 #[unstable(feature = "convert", reason = "recently added", issue = "27704")]
255 #[rustc_deprecated(reason = "RFC was closed, hides subtle Windows semantics",
257 pub fn to_bytes(&self) -> Option
<&[u8]> {
259 self.to_str().map(|s
| s
.as_bytes())
265 /// Creates a `CString` containing this `OsStr` data.
267 /// Fails if the `OsStr` contains interior nulls.
269 /// This is a convenience for creating a `CString` from
270 /// `self.to_bytes()`, and inherits the platform behavior of the
271 /// `to_bytes` method.
272 #[unstable(feature = "convert", reason = "recently added", issue = "27704")]
273 #[rustc_deprecated(reason = "RFC was closed, hides subtle Windows semantics",
276 pub fn to_cstring(&self) -> Option
<CString
> {
277 self.to_bytes().and_then(|b
| CString
::new(b
).ok())
280 /// Gets the underlying byte representation.
282 /// Note: it is *crucial* that this API is private, to avoid
283 /// revealing the internal, platform-specific encodings.
284 fn bytes(&self) -> &[u8] {
285 unsafe { mem::transmute(&self.inner) }
289 #[stable(feature = "rust1", since = "1.0.0")]
290 impl PartialEq
for OsStr
{
291 fn eq(&self, other
: &OsStr
) -> bool
{
292 self.bytes().eq(other
.bytes())
296 #[stable(feature = "rust1", since = "1.0.0")]
297 impl PartialEq
<str> for OsStr
{
298 fn eq(&self, other
: &str) -> bool
{
299 *self == *OsStr
::new(other
)
303 #[stable(feature = "rust1", since = "1.0.0")]
304 impl PartialEq
<OsStr
> for str {
305 fn eq(&self, other
: &OsStr
) -> bool
{
306 *other
== *OsStr
::new(self)
310 #[stable(feature = "rust1", since = "1.0.0")]
313 #[stable(feature = "rust1", since = "1.0.0")]
314 impl PartialOrd
for OsStr
{
316 fn partial_cmp(&self, other
: &OsStr
) -> Option
<cmp
::Ordering
> {
317 self.bytes().partial_cmp(other
.bytes())
320 fn lt(&self, other
: &OsStr
) -> bool { self.bytes().lt(other.bytes()) }
322 fn le(&self, other
: &OsStr
) -> bool { self.bytes().le(other.bytes()) }
324 fn gt(&self, other
: &OsStr
) -> bool { self.bytes().gt(other.bytes()) }
326 fn ge(&self, other
: &OsStr
) -> bool { self.bytes().ge(other.bytes()) }
329 #[stable(feature = "rust1", since = "1.0.0")]
330 impl PartialOrd
<str> for OsStr
{
332 fn partial_cmp(&self, other
: &str) -> Option
<cmp
::Ordering
> {
333 self.partial_cmp(OsStr
::new(other
))
337 // FIXME (#19470): cannot provide PartialOrd<OsStr> for str until we
338 // have more flexible coherence rules.
340 #[stable(feature = "rust1", since = "1.0.0")]
343 fn cmp(&self, other
: &OsStr
) -> cmp
::Ordering { self.bytes().cmp(other.bytes()) }
346 #[stable(feature = "rust1", since = "1.0.0")]
347 impl Hash
for OsStr
{
349 fn hash
<H
: Hasher
>(&self, state
: &mut H
) {
350 self.bytes().hash(state
)
354 #[stable(feature = "rust1", since = "1.0.0")]
355 impl Debug
for OsStr
{
356 fn fmt(&self, formatter
: &mut fmt
::Formatter
) -> Result
<(), fmt
::Error
> {
357 self.inner
.fmt(formatter
)
361 #[stable(feature = "rust1", since = "1.0.0")]
362 impl Borrow
<OsStr
> for OsString
{
363 fn borrow(&self) -> &OsStr { &self[..] }
366 #[stable(feature = "rust1", since = "1.0.0")]
367 impl ToOwned
for OsStr
{
368 type Owned
= OsString
;
369 fn to_owned(&self) -> OsString { self.to_os_string() }
372 #[stable(feature = "rust1", since = "1.0.0")]
373 impl AsRef
<OsStr
> for OsStr
{
374 fn as_ref(&self) -> &OsStr
{
379 #[stable(feature = "rust1", since = "1.0.0")]
380 impl AsRef
<OsStr
> for OsString
{
381 fn as_ref(&self) -> &OsStr
{
386 #[stable(feature = "rust1", since = "1.0.0")]
387 impl AsRef
<OsStr
> for str {
388 fn as_ref(&self) -> &OsStr
{
389 OsStr
::from_inner(Slice
::from_str(self))
393 #[stable(feature = "rust1", since = "1.0.0")]
394 impl AsRef
<OsStr
> for String
{
395 fn as_ref(&self) -> &OsStr
{
400 impl FromInner
<Buf
> for OsString
{
401 fn from_inner(buf
: Buf
) -> OsString
{
402 OsString { inner: buf }
406 impl IntoInner
<Buf
> for OsString
{
407 fn into_inner(self) -> Buf
{
412 impl AsInner
<Slice
> for OsStr
{
413 fn as_inner(&self) -> &Slice
{