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