]> git.lizzy.rs Git - rust.git/blob - src/libstd/ffi/os_str.rs
Auto merge of #53517 - phungleson:fix-impl-from-for-error, r=frewsxcv
[rust.git] / src / libstd / ffi / os_str.rs
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.
4 //
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.
10
11 use borrow::{Borrow, Cow};
12 use fmt;
13 use ops;
14 use cmp;
15 use hash::{Hash, Hasher};
16 use rc::Rc;
17 use sync::Arc;
18
19 use sys::os_str::{Buf, Slice};
20 use sys_common::{AsInner, IntoInner, FromInner};
21
22 /// A type that can represent owned, mutable platform-native strings, but is
23 /// cheaply inter-convertible with Rust strings.
24 ///
25 /// The need for this type arises from the fact that:
26 ///
27 /// * On Unix systems, strings are often arbitrary sequences of non-zero
28 ///   bytes, in many cases interpreted as UTF-8.
29 ///
30 /// * On Windows, strings are often arbitrary sequences of non-zero 16-bit
31 ///   values, interpreted as UTF-16 when it is valid to do so.
32 ///
33 /// * In Rust, strings are always valid UTF-8, which may contain zeros.
34 ///
35 /// `OsString` and [`OsStr`] bridge this gap by simultaneously representing Rust
36 /// and platform-native string values, and in particular allowing a Rust string
37 /// to be converted into an "OS" string with no cost if possible.  A consequence
38 /// of this is that `OsString` instances are *not* `NUL` terminated; in order
39 /// to pass to e.g. Unix system call, you should create a [`CStr`].
40 ///
41 /// `OsString` is to [`&OsStr`] as [`String`] is to [`&str`]: the former
42 /// in each pair are owned strings; the latter are borrowed
43 /// references.
44 ///
45 /// # Creating an `OsString`
46 ///
47 /// **From a Rust string**: `OsString` implements
48 /// [`From`]`<`[`String`]`>`, so you can use `my_string.from` to
49 /// create an `OsString` from a normal Rust string.
50 ///
51 /// **From slices:** Just like you can start with an empty Rust
52 /// [`String`] and then [`push_str`][String.push_str] `&str`
53 /// sub-string slices into it, you can create an empty `OsString` with
54 /// the [`new`] method and then push string slices into it with the
55 /// [`push`] method.
56 ///
57 /// # Extracting a borrowed reference to the whole OS string
58 ///
59 /// You can use the [`as_os_str`] method to get an `&`[`OsStr`] from
60 /// an `OsString`; this is effectively a borrowed reference to the
61 /// whole string.
62 ///
63 /// # Conversions
64 ///
65 /// See the [module's toplevel documentation about conversions][conversions] for a discussion on
66 /// the traits which `OsString` implements for [conversions] from/to native representations.
67 ///
68 /// [`OsStr`]: struct.OsStr.html
69 /// [`&OsStr`]: struct.OsStr.html
70 /// [`CStr`]: struct.CStr.html
71 /// [`From`]: ../convert/trait.From.html
72 /// [`String`]: ../string/struct.String.html
73 /// [`&str`]: ../primitive.str.html
74 /// [`u8`]: ../primitive.u8.html
75 /// [`u16`]: ../primitive.u16.html
76 /// [String.push_str]: ../string/struct.String.html#method.push_str
77 /// [`new`]: #method.new
78 /// [`push`]: #method.push
79 /// [`as_os_str`]: #method.as_os_str
80 /// [conversions]: index.html#conversions
81 #[derive(Clone)]
82 #[stable(feature = "rust1", since = "1.0.0")]
83 pub struct OsString {
84     inner: Buf
85 }
86
87 /// Borrowed reference to an OS string (see [`OsString`]).
88 ///
89 /// This type represents a borrowed reference to a string in the operating system's preferred
90 /// representation.
91 ///
92 /// `&OsStr` is to [`OsString`] as [`&str`] is to [`String`]: the former in each pair are borrowed
93 /// references; the latter are owned strings.
94 ///
95 /// See the [module's toplevel documentation about conversions][conversions] for a discussion on
96 /// the traits which `OsStr` implements for [conversions] from/to native representations.
97 ///
98 /// [`OsString`]: struct.OsString.html
99 /// [`&str`]: ../primitive.str.html
100 /// [`String`]: ../string/struct.String.html
101 /// [conversions]: index.html#conversions
102 #[stable(feature = "rust1", since = "1.0.0")]
103 pub struct OsStr {
104     inner: Slice
105 }
106
107 impl OsString {
108     /// Constructs a new empty `OsString`.
109     ///
110     /// # Examples
111     ///
112     /// ```
113     /// use std::ffi::OsString;
114     ///
115     /// let os_string = OsString::new();
116     /// ```
117     #[stable(feature = "rust1", since = "1.0.0")]
118     pub fn new() -> OsString {
119         OsString { inner: Buf::from_string(String::new()) }
120     }
121
122     /// Converts to an [`OsStr`] slice.
123     ///
124     /// [`OsStr`]: struct.OsStr.html
125     ///
126     /// # Examples
127     ///
128     /// ```
129     /// use std::ffi::{OsString, OsStr};
130     ///
131     /// let os_string = OsString::from("foo");
132     /// let os_str = OsStr::new("foo");
133     /// assert_eq!(os_string.as_os_str(), os_str);
134     /// ```
135     #[stable(feature = "rust1", since = "1.0.0")]
136     pub fn as_os_str(&self) -> &OsStr {
137         self
138     }
139
140     /// Converts the `OsString` into a [`String`] if it contains valid Unicode data.
141     ///
142     /// On failure, ownership of the original `OsString` is returned.
143     ///
144     /// [`String`]: ../../std/string/struct.String.html
145     ///
146     /// # Examples
147     ///
148     /// ```
149     /// use std::ffi::OsString;
150     ///
151     /// let os_string = OsString::from("foo");
152     /// let string = os_string.into_string();
153     /// assert_eq!(string, Ok(String::from("foo")));
154     /// ```
155     #[stable(feature = "rust1", since = "1.0.0")]
156     pub fn into_string(self) -> Result<String, OsString> {
157         self.inner.into_string().map_err(|buf| OsString { inner: buf} )
158     }
159
160     /// Extends the string with the given [`&OsStr`] slice.
161     ///
162     /// [`&OsStr`]: struct.OsStr.html
163     ///
164     /// # Examples
165     ///
166     /// ```
167     /// use std::ffi::OsString;
168     ///
169     /// let mut os_string = OsString::from("foo");
170     /// os_string.push("bar");
171     /// assert_eq!(&os_string, "foobar");
172     /// ```
173     #[stable(feature = "rust1", since = "1.0.0")]
174     pub fn push<T: AsRef<OsStr>>(&mut self, s: T) {
175         self.inner.push_slice(&s.as_ref().inner)
176     }
177
178     /// Creates a new `OsString` with the given capacity.
179     ///
180     /// The string will be able to hold exactly `capacity` length units of other
181     /// OS strings without reallocating. If `capacity` is 0, the string will not
182     /// allocate.
183     ///
184     /// See main `OsString` documentation information about encoding.
185     ///
186     /// # Examples
187     ///
188     /// ```
189     /// use std::ffi::OsString;
190     ///
191     /// let mut os_string = OsString::with_capacity(10);
192     /// let capacity = os_string.capacity();
193     ///
194     /// // This push is done without reallocating
195     /// os_string.push("foo");
196     ///
197     /// assert_eq!(capacity, os_string.capacity());
198     /// ```
199     #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
200     pub fn with_capacity(capacity: usize) -> OsString {
201         OsString {
202             inner: Buf::with_capacity(capacity)
203         }
204     }
205
206     /// Truncates the `OsString` to zero length.
207     ///
208     /// # Examples
209     ///
210     /// ```
211     /// use std::ffi::OsString;
212     ///
213     /// let mut os_string = OsString::from("foo");
214     /// assert_eq!(&os_string, "foo");
215     ///
216     /// os_string.clear();
217     /// assert_eq!(&os_string, "");
218     /// ```
219     #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
220     pub fn clear(&mut self) {
221         self.inner.clear()
222     }
223
224     /// Returns the capacity this `OsString` can hold without reallocating.
225     ///
226     /// See `OsString` introduction for information about encoding.
227     ///
228     /// # Examples
229     ///
230     /// ```
231     /// use std::ffi::OsString;
232     ///
233     /// let mut os_string = OsString::with_capacity(10);
234     /// assert!(os_string.capacity() >= 10);
235     /// ```
236     #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
237     pub fn capacity(&self) -> usize {
238         self.inner.capacity()
239     }
240
241     /// Reserves capacity for at least `additional` more capacity to be inserted
242     /// in the given `OsString`.
243     ///
244     /// The collection may reserve more space to avoid frequent reallocations.
245     ///
246     /// # Examples
247     ///
248     /// ```
249     /// use std::ffi::OsString;
250     ///
251     /// let mut s = OsString::new();
252     /// s.reserve(10);
253     /// assert!(s.capacity() >= 10);
254     /// ```
255     #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
256     pub fn reserve(&mut self, additional: usize) {
257         self.inner.reserve(additional)
258     }
259
260     /// Reserves the minimum capacity for exactly `additional` more capacity to
261     /// be inserted in the given `OsString`. Does nothing if the capacity is
262     /// already sufficient.
263     ///
264     /// Note that the allocator may give the collection more space than it
265     /// requests. Therefore capacity can not be relied upon to be precisely
266     /// minimal. Prefer reserve if future insertions are expected.
267     ///
268     /// # Examples
269     ///
270     /// ```
271     /// use std::ffi::OsString;
272     ///
273     /// let mut s = OsString::new();
274     /// s.reserve_exact(10);
275     /// assert!(s.capacity() >= 10);
276     /// ```
277     #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
278     pub fn reserve_exact(&mut self, additional: usize) {
279         self.inner.reserve_exact(additional)
280     }
281
282     /// Shrinks the capacity of the `OsString` to match its length.
283     ///
284     /// # Examples
285     ///
286     /// ```
287     /// use std::ffi::OsString;
288     ///
289     /// let mut s = OsString::from("foo");
290     ///
291     /// s.reserve(100);
292     /// assert!(s.capacity() >= 100);
293     ///
294     /// s.shrink_to_fit();
295     /// assert_eq!(3, s.capacity());
296     /// ```
297     #[stable(feature = "osstring_shrink_to_fit", since = "1.19.0")]
298     pub fn shrink_to_fit(&mut self) {
299         self.inner.shrink_to_fit()
300     }
301
302     /// Shrinks the capacity of the `OsString` with a lower bound.
303     ///
304     /// The capacity will remain at least as large as both the length
305     /// and the supplied value.
306     ///
307     /// Panics if the current capacity is smaller than the supplied
308     /// minimum capacity.
309     ///
310     /// # Examples
311     ///
312     /// ```
313     /// #![feature(shrink_to)]
314     /// use std::ffi::OsString;
315     ///
316     /// let mut s = OsString::from("foo");
317     ///
318     /// s.reserve(100);
319     /// assert!(s.capacity() >= 100);
320     ///
321     /// s.shrink_to(10);
322     /// assert!(s.capacity() >= 10);
323     /// s.shrink_to(0);
324     /// assert!(s.capacity() >= 3);
325     /// ```
326     #[inline]
327     #[unstable(feature = "shrink_to", reason = "new API", issue="0")]
328     pub fn shrink_to(&mut self, min_capacity: usize) {
329         self.inner.shrink_to(min_capacity)
330     }
331
332     /// Converts this `OsString` into a boxed [`OsStr`].
333     ///
334     /// [`OsStr`]: struct.OsStr.html
335     ///
336     /// # Examples
337     ///
338     /// ```
339     /// use std::ffi::{OsString, OsStr};
340     ///
341     /// let s = OsString::from("hello");
342     ///
343     /// let b: Box<OsStr> = s.into_boxed_os_str();
344     /// ```
345     #[stable(feature = "into_boxed_os_str", since = "1.20.0")]
346     pub fn into_boxed_os_str(self) -> Box<OsStr> {
347         let rw = Box::into_raw(self.inner.into_box()) as *mut OsStr;
348         unsafe { Box::from_raw(rw) }
349     }
350 }
351
352 #[stable(feature = "rust1", since = "1.0.0")]
353 impl From<String> for OsString {
354     /// Converts a [`String`] into a [`OsString`].
355     ///
356     /// The conversion copies the data, and includes an allocation on the heap.
357     fn from(s: String) -> OsString {
358         OsString { inner: Buf::from_string(s) }
359     }
360 }
361
362 #[stable(feature = "rust1", since = "1.0.0")]
363 impl<'a, T: ?Sized + AsRef<OsStr>> From<&'a T> for OsString {
364     fn from(s: &'a T) -> OsString {
365         s.as_ref().to_os_string()
366     }
367 }
368
369 #[stable(feature = "rust1", since = "1.0.0")]
370 impl ops::Index<ops::RangeFull> for OsString {
371     type Output = OsStr;
372
373     #[inline]
374     fn index(&self, _index: ops::RangeFull) -> &OsStr {
375         OsStr::from_inner(self.inner.as_slice())
376     }
377 }
378
379 #[stable(feature = "rust1", since = "1.0.0")]
380 impl ops::Deref for OsString {
381     type Target = OsStr;
382
383     #[inline]
384     fn deref(&self) -> &OsStr {
385         &self[..]
386     }
387 }
388
389 #[stable(feature = "osstring_default", since = "1.9.0")]
390 impl Default for OsString {
391     /// Constructs an empty `OsString`.
392     #[inline]
393     fn default() -> OsString {
394         OsString::new()
395     }
396 }
397
398 #[stable(feature = "rust1", since = "1.0.0")]
399 impl fmt::Debug for OsString {
400     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
401         fmt::Debug::fmt(&**self, formatter)
402     }
403 }
404
405 #[stable(feature = "rust1", since = "1.0.0")]
406 impl PartialEq for OsString {
407     fn eq(&self, other: &OsString) -> bool {
408         &**self == &**other
409     }
410 }
411
412 #[stable(feature = "rust1", since = "1.0.0")]
413 impl PartialEq<str> for OsString {
414     fn eq(&self, other: &str) -> bool {
415         &**self == other
416     }
417 }
418
419 #[stable(feature = "rust1", since = "1.0.0")]
420 impl PartialEq<OsString> for str {
421     fn eq(&self, other: &OsString) -> bool {
422         &**other == self
423     }
424 }
425
426 #[stable(feature = "os_str_str_ref_eq", since = "1.29.0")]
427 impl<'a> PartialEq<&'a str> for OsString {
428     fn eq(&self, other: &&'a str) -> bool {
429         **self == **other
430     }
431 }
432
433 #[stable(feature = "os_str_str_ref_eq", since = "1.29.0")]
434 impl<'a> PartialEq<OsString> for &'a str {
435     fn eq(&self, other: &OsString) -> bool {
436         **other == **self
437     }
438 }
439
440 #[stable(feature = "rust1", since = "1.0.0")]
441 impl Eq for OsString {}
442
443 #[stable(feature = "rust1", since = "1.0.0")]
444 impl PartialOrd for OsString {
445     #[inline]
446     fn partial_cmp(&self, other: &OsString) -> Option<cmp::Ordering> {
447         (&**self).partial_cmp(&**other)
448     }
449     #[inline]
450     fn lt(&self, other: &OsString) -> bool { &**self < &**other }
451     #[inline]
452     fn le(&self, other: &OsString) -> bool { &**self <= &**other }
453     #[inline]
454     fn gt(&self, other: &OsString) -> bool { &**self > &**other }
455     #[inline]
456     fn ge(&self, other: &OsString) -> bool { &**self >= &**other }
457 }
458
459 #[stable(feature = "rust1", since = "1.0.0")]
460 impl PartialOrd<str> for OsString {
461     #[inline]
462     fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
463         (&**self).partial_cmp(other)
464     }
465 }
466
467 #[stable(feature = "rust1", since = "1.0.0")]
468 impl Ord for OsString {
469     #[inline]
470     fn cmp(&self, other: &OsString) -> cmp::Ordering {
471         (&**self).cmp(&**other)
472     }
473 }
474
475 #[stable(feature = "rust1", since = "1.0.0")]
476 impl Hash for OsString {
477     #[inline]
478     fn hash<H: Hasher>(&self, state: &mut H) {
479         (&**self).hash(state)
480     }
481 }
482
483 impl OsStr {
484     /// Coerces into an `OsStr` slice.
485     ///
486     /// # Examples
487     ///
488     /// ```
489     /// use std::ffi::OsStr;
490     ///
491     /// let os_str = OsStr::new("foo");
492     /// ```
493     #[stable(feature = "rust1", since = "1.0.0")]
494     pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &OsStr {
495         s.as_ref()
496     }
497
498     fn from_inner(inner: &Slice) -> &OsStr {
499         unsafe { &*(inner as *const Slice as *const OsStr) }
500     }
501
502     /// Yields a [`&str`] slice if the `OsStr` is valid Unicode.
503     ///
504     /// This conversion may entail doing a check for UTF-8 validity.
505     ///
506     /// [`&str`]: ../../std/primitive.str.html
507     ///
508     /// # Examples
509     ///
510     /// ```
511     /// use std::ffi::OsStr;
512     ///
513     /// let os_str = OsStr::new("foo");
514     /// assert_eq!(os_str.to_str(), Some("foo"));
515     /// ```
516     #[stable(feature = "rust1", since = "1.0.0")]
517     pub fn to_str(&self) -> Option<&str> {
518         self.inner.to_str()
519     }
520
521     /// Converts an `OsStr` to a [`Cow`]`<`[`str`]`>`.
522     ///
523     /// Any non-Unicode sequences are replaced with
524     /// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD].
525     ///
526     /// [`Cow`]: ../../std/borrow/enum.Cow.html
527     /// [`str`]: ../../std/primitive.str.html
528     /// [U+FFFD]: ../../std/char/constant.REPLACEMENT_CHARACTER.html
529     ///
530     /// # Examples
531     ///
532     /// Calling `to_string_lossy` on an `OsStr` with valid unicode:
533     ///
534     /// ```
535     /// use std::ffi::OsStr;
536     ///
537     /// let os_str = OsStr::new("foo");
538     /// assert_eq!(os_str.to_string_lossy(), "foo");
539     /// ```
540     ///
541     /// Had `os_str` contained invalid unicode, the `to_string_lossy` call might
542     /// have returned `"fo�"`.
543     #[stable(feature = "rust1", since = "1.0.0")]
544     pub fn to_string_lossy(&self) -> Cow<str> {
545         self.inner.to_string_lossy()
546     }
547
548     /// Copies the slice into an owned [`OsString`].
549     ///
550     /// [`OsString`]: struct.OsString.html
551     ///
552     /// # Examples
553     ///
554     /// ```
555     /// use std::ffi::{OsStr, OsString};
556     ///
557     /// let os_str = OsStr::new("foo");
558     /// let os_string = os_str.to_os_string();
559     /// assert_eq!(os_string, OsString::from("foo"));
560     /// ```
561     #[stable(feature = "rust1", since = "1.0.0")]
562     pub fn to_os_string(&self) -> OsString {
563         OsString { inner: self.inner.to_owned() }
564     }
565
566     /// Checks whether the `OsStr` is empty.
567     ///
568     /// # Examples
569     ///
570     /// ```
571     /// use std::ffi::OsStr;
572     ///
573     /// let os_str = OsStr::new("");
574     /// assert!(os_str.is_empty());
575     ///
576     /// let os_str = OsStr::new("foo");
577     /// assert!(!os_str.is_empty());
578     /// ```
579     #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
580     pub fn is_empty(&self) -> bool {
581         self.inner.inner.is_empty()
582     }
583
584     /// Returns the length of this `OsStr`.
585     ///
586     /// Note that this does **not** return the number of bytes in this string
587     /// as, for example, OS strings on Windows are encoded as a list of [`u16`]
588     /// rather than a list of bytes. This number is simply useful for passing to
589     /// other methods like [`OsString::with_capacity`] to avoid reallocations.
590     ///
591     /// See `OsStr` introduction for more information about encoding.
592     ///
593     /// [`u16`]: ../primitive.u16.html
594     /// [`OsString::with_capacity`]: struct.OsString.html#method.with_capacity
595     ///
596     /// # Examples
597     ///
598     /// ```
599     /// use std::ffi::OsStr;
600     ///
601     /// let os_str = OsStr::new("");
602     /// assert_eq!(os_str.len(), 0);
603     ///
604     /// let os_str = OsStr::new("foo");
605     /// assert_eq!(os_str.len(), 3);
606     /// ```
607     #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
608     pub fn len(&self) -> usize {
609         self.inner.inner.len()
610     }
611
612     /// Converts a [`Box`]`<OsStr>` into an [`OsString`] without copying or allocating.
613     ///
614     /// [`Box`]: ../boxed/struct.Box.html
615     /// [`OsString`]: struct.OsString.html
616     #[stable(feature = "into_boxed_os_str", since = "1.20.0")]
617     pub fn into_os_string(self: Box<OsStr>) -> OsString {
618         let boxed = unsafe { Box::from_raw(Box::into_raw(self) as *mut Slice) };
619         OsString { inner: Buf::from_box(boxed) }
620     }
621
622     /// Gets the underlying byte representation.
623     ///
624     /// Note: it is *crucial* that this API is private, to avoid
625     /// revealing the internal, platform-specific encodings.
626     fn bytes(&self) -> &[u8] {
627         unsafe { &*(&self.inner as *const _ as *const [u8]) }
628     }
629 }
630
631 #[stable(feature = "box_from_os_str", since = "1.17.0")]
632 impl<'a> From<&'a OsStr> for Box<OsStr> {
633     fn from(s: &'a OsStr) -> Box<OsStr> {
634         let rw = Box::into_raw(s.inner.into_box()) as *mut OsStr;
635         unsafe { Box::from_raw(rw) }
636     }
637 }
638
639 #[stable(feature = "os_string_from_box", since = "1.18.0")]
640 impl From<Box<OsStr>> for OsString {
641     /// Converts a `Box<OsStr>` into a `OsString` without copying or allocating.
642     ///
643     /// [`Box`]: ../boxed/struct.Box.html
644     /// [`OsString`]: ../ffi/struct.OsString.html
645     fn from(boxed: Box<OsStr>) -> OsString {
646         boxed.into_os_string()
647     }
648 }
649
650 #[stable(feature = "box_from_os_string", since = "1.20.0")]
651 impl From<OsString> for Box<OsStr> {
652     /// Converts a [`OsString`] into a [`Box`]`<OsStr>` without copying or allocating.
653     ///
654     /// [`Box`]: ../boxed/struct.Box.html
655     /// [`OsString`]: ../ffi/struct.OsString.html
656     fn from(s: OsString) -> Box<OsStr> {
657         s.into_boxed_os_str()
658     }
659 }
660
661 #[stable(feature = "more_box_slice_clone", since = "1.29.0")]
662 impl Clone for Box<OsStr> {
663     #[inline]
664     fn clone(&self) -> Self {
665         self.to_os_string().into_boxed_os_str()
666     }
667 }
668
669 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
670 impl From<OsString> for Arc<OsStr> {
671     /// Converts a [`OsString`] into a [`Arc`]`<OsStr>` without copying or allocating.
672     ///
673     /// [`Arc`]: ../sync/struct.Arc.html
674     /// [`OsString`]: ../ffi/struct.OsString.html
675     #[inline]
676     fn from(s: OsString) -> Arc<OsStr> {
677         let arc = s.inner.into_arc();
678         unsafe { Arc::from_raw(Arc::into_raw(arc) as *const OsStr) }
679     }
680 }
681
682 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
683 impl<'a> From<&'a OsStr> for Arc<OsStr> {
684     #[inline]
685     fn from(s: &OsStr) -> Arc<OsStr> {
686         let arc = s.inner.into_arc();
687         unsafe { Arc::from_raw(Arc::into_raw(arc) as *const OsStr) }
688     }
689 }
690
691 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
692 impl From<OsString> for Rc<OsStr> {
693     /// Converts a [`OsString`] into a [`Rc`]`<OsStr>` without copying or allocating.
694     ///
695     /// [`Rc`]: ../rc/struct.Rc.html
696     /// [`OsString`]: ../ffi/struct.OsString.html
697     #[inline]
698     fn from(s: OsString) -> Rc<OsStr> {
699         let rc = s.inner.into_rc();
700         unsafe { Rc::from_raw(Rc::into_raw(rc) as *const OsStr) }
701     }
702 }
703
704 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
705 impl<'a> From<&'a OsStr> for Rc<OsStr> {
706     #[inline]
707     fn from(s: &OsStr) -> Rc<OsStr> {
708         let rc = s.inner.into_rc();
709         unsafe { Rc::from_raw(Rc::into_raw(rc) as *const OsStr) }
710     }
711 }
712
713 #[stable(feature = "cow_from_osstr", since = "1.28.0")]
714 impl<'a> From<OsString> for Cow<'a, OsStr> {
715     #[inline]
716     fn from(s: OsString) -> Cow<'a, OsStr> {
717         Cow::Owned(s)
718     }
719 }
720
721 #[stable(feature = "cow_from_osstr", since = "1.28.0")]
722 impl<'a> From<&'a OsStr> for Cow<'a, OsStr> {
723     #[inline]
724     fn from(s: &'a OsStr) -> Cow<'a, OsStr> {
725         Cow::Borrowed(s)
726     }
727 }
728
729 #[stable(feature = "cow_from_osstr", since = "1.28.0")]
730 impl<'a> From<&'a OsString> for Cow<'a, OsStr> {
731     #[inline]
732     fn from(s: &'a OsString) -> Cow<'a, OsStr> {
733         Cow::Borrowed(s.as_os_str())
734     }
735 }
736
737 #[stable(feature = "osstring_from_cow_osstr", since = "1.28.0")]
738 impl<'a> From<Cow<'a, OsStr>> for OsString {
739     #[inline]
740     fn from(s: Cow<'a, OsStr>) -> Self {
741         s.into_owned()
742     }
743 }
744
745 #[stable(feature = "box_default_extra", since = "1.17.0")]
746 impl Default for Box<OsStr> {
747     fn default() -> Box<OsStr> {
748         let rw = Box::into_raw(Slice::empty_box()) as *mut OsStr;
749         unsafe { Box::from_raw(rw) }
750     }
751 }
752
753 #[stable(feature = "osstring_default", since = "1.9.0")]
754 impl<'a> Default for &'a OsStr {
755     /// Creates an empty `OsStr`.
756     #[inline]
757     fn default() -> &'a OsStr {
758         OsStr::new("")
759     }
760 }
761
762 #[stable(feature = "rust1", since = "1.0.0")]
763 impl PartialEq for OsStr {
764     fn eq(&self, other: &OsStr) -> bool {
765         self.bytes().eq(other.bytes())
766     }
767 }
768
769 #[stable(feature = "rust1", since = "1.0.0")]
770 impl PartialEq<str> for OsStr {
771     fn eq(&self, other: &str) -> bool {
772         *self == *OsStr::new(other)
773     }
774 }
775
776 #[stable(feature = "rust1", since = "1.0.0")]
777 impl PartialEq<OsStr> for str {
778     fn eq(&self, other: &OsStr) -> bool {
779         *other == *OsStr::new(self)
780     }
781 }
782
783 #[stable(feature = "rust1", since = "1.0.0")]
784 impl Eq for OsStr {}
785
786 #[stable(feature = "rust1", since = "1.0.0")]
787 impl PartialOrd for OsStr {
788     #[inline]
789     fn partial_cmp(&self, other: &OsStr) -> Option<cmp::Ordering> {
790         self.bytes().partial_cmp(other.bytes())
791     }
792     #[inline]
793     fn lt(&self, other: &OsStr) -> bool { self.bytes().lt(other.bytes()) }
794     #[inline]
795     fn le(&self, other: &OsStr) -> bool { self.bytes().le(other.bytes()) }
796     #[inline]
797     fn gt(&self, other: &OsStr) -> bool { self.bytes().gt(other.bytes()) }
798     #[inline]
799     fn ge(&self, other: &OsStr) -> bool { self.bytes().ge(other.bytes()) }
800 }
801
802 #[stable(feature = "rust1", since = "1.0.0")]
803 impl PartialOrd<str> for OsStr {
804     #[inline]
805     fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
806         self.partial_cmp(OsStr::new(other))
807     }
808 }
809
810 // FIXME (#19470): cannot provide PartialOrd<OsStr> for str until we
811 // have more flexible coherence rules.
812
813 #[stable(feature = "rust1", since = "1.0.0")]
814 impl Ord for OsStr {
815     #[inline]
816     fn cmp(&self, other: &OsStr) -> cmp::Ordering { self.bytes().cmp(other.bytes()) }
817 }
818
819 macro_rules! impl_cmp {
820     ($lhs:ty, $rhs: ty) => {
821         #[stable(feature = "cmp_os_str", since = "1.8.0")]
822         impl<'a, 'b> PartialEq<$rhs> for $lhs {
823             #[inline]
824             fn eq(&self, other: &$rhs) -> bool { <OsStr as PartialEq>::eq(self, other) }
825         }
826
827         #[stable(feature = "cmp_os_str", since = "1.8.0")]
828         impl<'a, 'b> PartialEq<$lhs> for $rhs {
829             #[inline]
830             fn eq(&self, other: &$lhs) -> bool { <OsStr as PartialEq>::eq(self, other) }
831         }
832
833         #[stable(feature = "cmp_os_str", since = "1.8.0")]
834         impl<'a, 'b> PartialOrd<$rhs> for $lhs {
835             #[inline]
836             fn partial_cmp(&self, other: &$rhs) -> Option<cmp::Ordering> {
837                 <OsStr as PartialOrd>::partial_cmp(self, other)
838             }
839         }
840
841         #[stable(feature = "cmp_os_str", since = "1.8.0")]
842         impl<'a, 'b> PartialOrd<$lhs> for $rhs {
843             #[inline]
844             fn partial_cmp(&self, other: &$lhs) -> Option<cmp::Ordering> {
845                 <OsStr as PartialOrd>::partial_cmp(self, other)
846             }
847         }
848     }
849 }
850
851 impl_cmp!(OsString, OsStr);
852 impl_cmp!(OsString, &'a OsStr);
853 impl_cmp!(Cow<'a, OsStr>, OsStr);
854 impl_cmp!(Cow<'a, OsStr>, &'b OsStr);
855 impl_cmp!(Cow<'a, OsStr>, OsString);
856
857 #[stable(feature = "rust1", since = "1.0.0")]
858 impl Hash for OsStr {
859     #[inline]
860     fn hash<H: Hasher>(&self, state: &mut H) {
861         self.bytes().hash(state)
862     }
863 }
864
865 #[stable(feature = "rust1", since = "1.0.0")]
866 impl fmt::Debug for OsStr {
867     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
868         fmt::Debug::fmt(&self.inner, formatter)
869     }
870 }
871
872 impl OsStr {
873     pub(crate) fn display(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
874         fmt::Display::fmt(&self.inner, formatter)
875     }
876 }
877
878 #[stable(feature = "rust1", since = "1.0.0")]
879 impl Borrow<OsStr> for OsString {
880     fn borrow(&self) -> &OsStr { &self[..] }
881 }
882
883 #[stable(feature = "rust1", since = "1.0.0")]
884 impl ToOwned for OsStr {
885     type Owned = OsString;
886     fn to_owned(&self) -> OsString {
887         self.to_os_string()
888     }
889     fn clone_into(&self, target: &mut OsString) {
890         target.clear();
891         target.push(self);
892     }
893 }
894
895 #[stable(feature = "rust1", since = "1.0.0")]
896 impl AsRef<OsStr> for OsStr {
897     fn as_ref(&self) -> &OsStr {
898         self
899     }
900 }
901
902 #[stable(feature = "rust1", since = "1.0.0")]
903 impl AsRef<OsStr> for OsString {
904     fn as_ref(&self) -> &OsStr {
905         self
906     }
907 }
908
909 #[stable(feature = "rust1", since = "1.0.0")]
910 impl AsRef<OsStr> for str {
911     fn as_ref(&self) -> &OsStr {
912         OsStr::from_inner(Slice::from_str(self))
913     }
914 }
915
916 #[stable(feature = "rust1", since = "1.0.0")]
917 impl AsRef<OsStr> for String {
918     fn as_ref(&self) -> &OsStr {
919         (&**self).as_ref()
920     }
921 }
922
923 impl FromInner<Buf> for OsString {
924     fn from_inner(buf: Buf) -> OsString {
925         OsString { inner: buf }
926     }
927 }
928
929 impl IntoInner<Buf> for OsString {
930     fn into_inner(self) -> Buf {
931         self.inner
932     }
933 }
934
935 impl AsInner<Slice> for OsStr {
936     fn as_inner(&self) -> &Slice {
937         &self.inner
938     }
939 }
940
941 #[cfg(test)]
942 mod tests {
943     use super::*;
944     use sys_common::{AsInner, IntoInner};
945
946     use rc::Rc;
947     use sync::Arc;
948
949     #[test]
950     fn test_os_string_with_capacity() {
951         let os_string = OsString::with_capacity(0);
952         assert_eq!(0, os_string.inner.into_inner().capacity());
953
954         let os_string = OsString::with_capacity(10);
955         assert_eq!(10, os_string.inner.into_inner().capacity());
956
957         let mut os_string = OsString::with_capacity(0);
958         os_string.push("abc");
959         assert!(os_string.inner.into_inner().capacity() >= 3);
960     }
961
962     #[test]
963     fn test_os_string_clear() {
964         let mut os_string = OsString::from("abc");
965         assert_eq!(3, os_string.inner.as_inner().len());
966
967         os_string.clear();
968         assert_eq!(&os_string, "");
969         assert_eq!(0, os_string.inner.as_inner().len());
970     }
971
972     #[test]
973     fn test_os_string_capacity() {
974         let os_string = OsString::with_capacity(0);
975         assert_eq!(0, os_string.capacity());
976
977         let os_string = OsString::with_capacity(10);
978         assert_eq!(10, os_string.capacity());
979
980         let mut os_string = OsString::with_capacity(0);
981         os_string.push("abc");
982         assert!(os_string.capacity() >= 3);
983     }
984
985     #[test]
986     fn test_os_string_reserve() {
987         let mut os_string = OsString::new();
988         assert_eq!(os_string.capacity(), 0);
989
990         os_string.reserve(2);
991         assert!(os_string.capacity() >= 2);
992
993         for _ in 0..16 {
994             os_string.push("a");
995         }
996
997         assert!(os_string.capacity() >= 16);
998         os_string.reserve(16);
999         assert!(os_string.capacity() >= 32);
1000
1001         os_string.push("a");
1002
1003         os_string.reserve(16);
1004         assert!(os_string.capacity() >= 33)
1005     }
1006
1007     #[test]
1008     fn test_os_string_reserve_exact() {
1009         let mut os_string = OsString::new();
1010         assert_eq!(os_string.capacity(), 0);
1011
1012         os_string.reserve_exact(2);
1013         assert!(os_string.capacity() >= 2);
1014
1015         for _ in 0..16 {
1016             os_string.push("a");
1017         }
1018
1019         assert!(os_string.capacity() >= 16);
1020         os_string.reserve_exact(16);
1021         assert!(os_string.capacity() >= 32);
1022
1023         os_string.push("a");
1024
1025         os_string.reserve_exact(16);
1026         assert!(os_string.capacity() >= 33)
1027     }
1028
1029     #[test]
1030     fn test_os_string_default() {
1031         let os_string: OsString = Default::default();
1032         assert_eq!("", &os_string);
1033     }
1034
1035     #[test]
1036     fn test_os_str_is_empty() {
1037         let mut os_string = OsString::new();
1038         assert!(os_string.is_empty());
1039
1040         os_string.push("abc");
1041         assert!(!os_string.is_empty());
1042
1043         os_string.clear();
1044         assert!(os_string.is_empty());
1045     }
1046
1047     #[test]
1048     fn test_os_str_len() {
1049         let mut os_string = OsString::new();
1050         assert_eq!(0, os_string.len());
1051
1052         os_string.push("abc");
1053         assert_eq!(3, os_string.len());
1054
1055         os_string.clear();
1056         assert_eq!(0, os_string.len());
1057     }
1058
1059     #[test]
1060     fn test_os_str_default() {
1061         let os_str: &OsStr = Default::default();
1062         assert_eq!("", os_str);
1063     }
1064
1065     #[test]
1066     fn into_boxed() {
1067         let orig = "Hello, world!";
1068         let os_str = OsStr::new(orig);
1069         let boxed: Box<OsStr> = Box::from(os_str);
1070         let os_string = os_str.to_owned().into_boxed_os_str().into_os_string();
1071         assert_eq!(os_str, &*boxed);
1072         assert_eq!(&*boxed, &*os_string);
1073         assert_eq!(&*os_string, os_str);
1074     }
1075
1076     #[test]
1077     fn boxed_default() {
1078         let boxed = <Box<OsStr>>::default();
1079         assert!(boxed.is_empty());
1080     }
1081
1082     #[test]
1083     fn test_os_str_clone_into() {
1084         let mut os_string = OsString::with_capacity(123);
1085         os_string.push("hello");
1086         let os_str = OsStr::new("bonjour");
1087         os_str.clone_into(&mut os_string);
1088         assert_eq!(os_str, os_string);
1089         assert!(os_string.capacity() >= 123);
1090     }
1091
1092     #[test]
1093     fn into_rc() {
1094         let orig = "Hello, world!";
1095         let os_str = OsStr::new(orig);
1096         let rc: Rc<OsStr> = Rc::from(os_str);
1097         let arc: Arc<OsStr> = Arc::from(os_str);
1098
1099         assert_eq!(&*rc, os_str);
1100         assert_eq!(&*arc, os_str);
1101
1102         let rc2: Rc<OsStr> = Rc::from(os_str.to_owned());
1103         let arc2: Arc<OsStr> = Arc::from(os_str.to_owned());
1104
1105         assert_eq!(&*rc2, os_str);
1106         assert_eq!(&*arc2, os_str);
1107     }
1108 }