]> git.lizzy.rs Git - rust.git/blob - src/libstd/ffi/os_str.rs
Add riscv64gc-unknown-none-elf target
[rust.git] / src / libstd / ffi / os_str.rs
1 use borrow::{Borrow, Cow};
2 use fmt;
3 use ops;
4 use cmp;
5 use hash::{Hash, Hasher};
6 use rc::Rc;
7 use sync::Arc;
8
9 use sys::os_str::{Buf, Slice};
10 use sys_common::{AsInner, IntoInner, FromInner};
11
12 /// A type that can represent owned, mutable platform-native strings, but is
13 /// cheaply inter-convertible with Rust strings.
14 ///
15 /// The need for this type arises from the fact that:
16 ///
17 /// * On Unix systems, strings are often arbitrary sequences of non-zero
18 ///   bytes, in many cases interpreted as UTF-8.
19 ///
20 /// * On Windows, strings are often arbitrary sequences of non-zero 16-bit
21 ///   values, interpreted as UTF-16 when it is valid to do so.
22 ///
23 /// * In Rust, strings are always valid UTF-8, which may contain zeros.
24 ///
25 /// `OsString` and [`OsStr`] bridge this gap by simultaneously representing Rust
26 /// and platform-native string values, and in particular allowing a Rust string
27 /// to be converted into an "OS" string with no cost if possible.  A consequence
28 /// of this is that `OsString` instances are *not* `NUL` terminated; in order
29 /// to pass to e.g., Unix system call, you should create a [`CStr`].
30 ///
31 /// `OsString` is to [`&OsStr`] as [`String`] is to [`&str`]: the former
32 /// in each pair are owned strings; the latter are borrowed
33 /// references.
34 ///
35 /// Note, `OsString` and `OsStr` internally do not necessarily hold strings in
36 /// the form native to the platform; While on Unix, strings are stored as a
37 /// sequence of 8-bit values, on Windows, where strings are 16-bit value based
38 /// as just discussed, strings are also actually stored as a sequence of 8-bit
39 /// values, encoded in a less-strict variant of UTF-8. This is useful to
40 /// understand when handling capacity and length values.
41 ///
42 /// # Creating an `OsString`
43 ///
44 /// **From a Rust string**: `OsString` implements
45 /// [`From`]`<`[`String`]`>`, so you can use `my_string.from` to
46 /// create an `OsString` from a normal Rust string.
47 ///
48 /// **From slices:** Just like you can start with an empty Rust
49 /// [`String`] and then [`push_str`][String.push_str] `&str`
50 /// sub-string slices into it, you can create an empty `OsString` with
51 /// the [`new`] method and then push string slices into it with the
52 /// [`push`] method.
53 ///
54 /// # Extracting a borrowed reference to the whole OS string
55 ///
56 /// You can use the [`as_os_str`] method to get an `&`[`OsStr`] from
57 /// an `OsString`; this is effectively a borrowed reference to the
58 /// whole string.
59 ///
60 /// # Conversions
61 ///
62 /// See the [module's toplevel documentation about conversions][conversions] for a discussion on
63 /// the traits which `OsString` implements for [conversions] from/to native representations.
64 ///
65 /// [`OsStr`]: struct.OsStr.html
66 /// [`&OsStr`]: struct.OsStr.html
67 /// [`CStr`]: struct.CStr.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="56431")]
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 invalid unicode:
530     ///
531     /// ```
532     /// // Note, due to differences in how Unix and Windows represent strings,
533     /// // we are forced to complicate this example, setting up example `OsStr`s
534     /// // with different source data and via different platform extensions.
535     /// // Understand that in reality you could end up with such example invalid
536     /// // sequences simply through collecting user command line arguments, for
537     /// // example.
538     ///
539     /// #[cfg(any(unix, target_os = "redox"))] {
540     ///     use std::ffi::OsStr;
541     ///     use std::os::unix::ffi::OsStrExt;
542     ///
543     ///     // Here, the values 0x66 and 0x6f correspond to 'f' and 'o'
544     ///     // respectively. The value 0x80 is a lone continuation byte, invalid
545     ///     // in a UTF-8 sequence.
546     ///     let source = [0x66, 0x6f, 0x80, 0x6f];
547     ///     let os_str = OsStr::from_bytes(&source[..]);
548     ///
549     ///     assert_eq!(os_str.to_string_lossy(), "fo�o");
550     /// }
551     /// #[cfg(windows)] {
552     ///     use std::ffi::OsString;
553     ///     use std::os::windows::prelude::*;
554     ///
555     ///     // Here the values 0x0066 and 0x006f correspond to 'f' and 'o'
556     ///     // respectively. The value 0xD800 is a lone surrogate half, invalid
557     ///     // in a UTF-16 sequence.
558     ///     let source = [0x0066, 0x006f, 0xD800, 0x006f];
559     ///     let os_string = OsString::from_wide(&source[..]);
560     ///     let os_str = os_string.as_os_str();
561     ///
562     ///     assert_eq!(os_str.to_string_lossy(), "fo�o");
563     /// }
564     /// ```
565     #[stable(feature = "rust1", since = "1.0.0")]
566     pub fn to_string_lossy(&self) -> Cow<str> {
567         self.inner.to_string_lossy()
568     }
569
570     /// Copies the slice into an owned [`OsString`].
571     ///
572     /// [`OsString`]: struct.OsString.html
573     ///
574     /// # Examples
575     ///
576     /// ```
577     /// use std::ffi::{OsStr, OsString};
578     ///
579     /// let os_str = OsStr::new("foo");
580     /// let os_string = os_str.to_os_string();
581     /// assert_eq!(os_string, OsString::from("foo"));
582     /// ```
583     #[stable(feature = "rust1", since = "1.0.0")]
584     pub fn to_os_string(&self) -> OsString {
585         OsString { inner: self.inner.to_owned() }
586     }
587
588     /// Checks whether the `OsStr` is empty.
589     ///
590     /// # Examples
591     ///
592     /// ```
593     /// use std::ffi::OsStr;
594     ///
595     /// let os_str = OsStr::new("");
596     /// assert!(os_str.is_empty());
597     ///
598     /// let os_str = OsStr::new("foo");
599     /// assert!(!os_str.is_empty());
600     /// ```
601     #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
602     pub fn is_empty(&self) -> bool {
603         self.inner.inner.is_empty()
604     }
605
606     /// Returns the length of this `OsStr`.
607     ///
608     /// Note that this does **not** return the number of bytes in the string in
609     /// OS string form.
610     ///
611     /// The length returned is that of the underlying storage used by `OsStr`;
612     /// As discussed in the [`OsString`] introduction, [`OsString`] and `OsStr`
613     /// store strings in a form best suited for cheap inter-conversion between
614     /// native-platform and Rust string forms, which may differ significantly
615     /// from both of them, including in storage size and encoding.
616     ///
617     /// This number is simply useful for passing to other methods, like
618     /// [`OsString::with_capacity`] to avoid reallocations.
619     ///
620     /// [`OsString`]: struct.OsString.html
621     /// [`OsString::with_capacity`]: struct.OsString.html#method.with_capacity
622     ///
623     /// # Examples
624     ///
625     /// ```
626     /// use std::ffi::OsStr;
627     ///
628     /// let os_str = OsStr::new("");
629     /// assert_eq!(os_str.len(), 0);
630     ///
631     /// let os_str = OsStr::new("foo");
632     /// assert_eq!(os_str.len(), 3);
633     /// ```
634     #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
635     pub fn len(&self) -> usize {
636         self.inner.inner.len()
637     }
638
639     /// Converts a [`Box`]`<OsStr>` into an [`OsString`] without copying or allocating.
640     ///
641     /// [`Box`]: ../boxed/struct.Box.html
642     /// [`OsString`]: struct.OsString.html
643     #[stable(feature = "into_boxed_os_str", since = "1.20.0")]
644     pub fn into_os_string(self: Box<OsStr>) -> OsString {
645         let boxed = unsafe { Box::from_raw(Box::into_raw(self) as *mut Slice) };
646         OsString { inner: Buf::from_box(boxed) }
647     }
648
649     /// Gets the underlying byte representation.
650     ///
651     /// Note: it is *crucial* that this API is private, to avoid
652     /// revealing the internal, platform-specific encodings.
653     fn bytes(&self) -> &[u8] {
654         unsafe { &*(&self.inner as *const _ as *const [u8]) }
655     }
656 }
657
658 #[stable(feature = "box_from_os_str", since = "1.17.0")]
659 impl<'a> From<&'a OsStr> for Box<OsStr> {
660     fn from(s: &'a OsStr) -> Box<OsStr> {
661         let rw = Box::into_raw(s.inner.into_box()) as *mut OsStr;
662         unsafe { Box::from_raw(rw) }
663     }
664 }
665
666 #[stable(feature = "os_string_from_box", since = "1.18.0")]
667 impl From<Box<OsStr>> for OsString {
668     /// Converts a `Box<OsStr>` into a `OsString` without copying or allocating.
669     ///
670     /// [`Box`]: ../boxed/struct.Box.html
671     /// [`OsString`]: ../ffi/struct.OsString.html
672     fn from(boxed: Box<OsStr>) -> OsString {
673         boxed.into_os_string()
674     }
675 }
676
677 #[stable(feature = "box_from_os_string", since = "1.20.0")]
678 impl From<OsString> for Box<OsStr> {
679     /// Converts a [`OsString`] into a [`Box`]`<OsStr>` without copying or allocating.
680     ///
681     /// [`Box`]: ../boxed/struct.Box.html
682     /// [`OsString`]: ../ffi/struct.OsString.html
683     fn from(s: OsString) -> Box<OsStr> {
684         s.into_boxed_os_str()
685     }
686 }
687
688 #[stable(feature = "more_box_slice_clone", since = "1.29.0")]
689 impl Clone for Box<OsStr> {
690     #[inline]
691     fn clone(&self) -> Self {
692         self.to_os_string().into_boxed_os_str()
693     }
694 }
695
696 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
697 impl From<OsString> for Arc<OsStr> {
698     /// Converts a [`OsString`] into a [`Arc`]`<OsStr>` without copying or allocating.
699     ///
700     /// [`Arc`]: ../sync/struct.Arc.html
701     /// [`OsString`]: ../ffi/struct.OsString.html
702     #[inline]
703     fn from(s: OsString) -> Arc<OsStr> {
704         let arc = s.inner.into_arc();
705         unsafe { Arc::from_raw(Arc::into_raw(arc) as *const OsStr) }
706     }
707 }
708
709 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
710 impl<'a> From<&'a OsStr> for Arc<OsStr> {
711     #[inline]
712     fn from(s: &OsStr) -> Arc<OsStr> {
713         let arc = s.inner.into_arc();
714         unsafe { Arc::from_raw(Arc::into_raw(arc) as *const OsStr) }
715     }
716 }
717
718 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
719 impl From<OsString> for Rc<OsStr> {
720     /// Converts a [`OsString`] into a [`Rc`]`<OsStr>` without copying or allocating.
721     ///
722     /// [`Rc`]: ../rc/struct.Rc.html
723     /// [`OsString`]: ../ffi/struct.OsString.html
724     #[inline]
725     fn from(s: OsString) -> Rc<OsStr> {
726         let rc = s.inner.into_rc();
727         unsafe { Rc::from_raw(Rc::into_raw(rc) as *const OsStr) }
728     }
729 }
730
731 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
732 impl<'a> From<&'a OsStr> for Rc<OsStr> {
733     #[inline]
734     fn from(s: &OsStr) -> Rc<OsStr> {
735         let rc = s.inner.into_rc();
736         unsafe { Rc::from_raw(Rc::into_raw(rc) as *const OsStr) }
737     }
738 }
739
740 #[stable(feature = "cow_from_osstr", since = "1.28.0")]
741 impl<'a> From<OsString> for Cow<'a, OsStr> {
742     #[inline]
743     fn from(s: OsString) -> Cow<'a, OsStr> {
744         Cow::Owned(s)
745     }
746 }
747
748 #[stable(feature = "cow_from_osstr", since = "1.28.0")]
749 impl<'a> From<&'a OsStr> for Cow<'a, OsStr> {
750     #[inline]
751     fn from(s: &'a OsStr) -> Cow<'a, OsStr> {
752         Cow::Borrowed(s)
753     }
754 }
755
756 #[stable(feature = "cow_from_osstr", since = "1.28.0")]
757 impl<'a> From<&'a OsString> for Cow<'a, OsStr> {
758     #[inline]
759     fn from(s: &'a OsString) -> Cow<'a, OsStr> {
760         Cow::Borrowed(s.as_os_str())
761     }
762 }
763
764 #[stable(feature = "osstring_from_cow_osstr", since = "1.28.0")]
765 impl<'a> From<Cow<'a, OsStr>> for OsString {
766     #[inline]
767     fn from(s: Cow<'a, OsStr>) -> Self {
768         s.into_owned()
769     }
770 }
771
772 #[stable(feature = "box_default_extra", since = "1.17.0")]
773 impl Default for Box<OsStr> {
774     fn default() -> Box<OsStr> {
775         let rw = Box::into_raw(Slice::empty_box()) as *mut OsStr;
776         unsafe { Box::from_raw(rw) }
777     }
778 }
779
780 #[stable(feature = "osstring_default", since = "1.9.0")]
781 impl<'a> Default for &'a OsStr {
782     /// Creates an empty `OsStr`.
783     #[inline]
784     fn default() -> &'a OsStr {
785         OsStr::new("")
786     }
787 }
788
789 #[stable(feature = "rust1", since = "1.0.0")]
790 impl PartialEq for OsStr {
791     fn eq(&self, other: &OsStr) -> bool {
792         self.bytes().eq(other.bytes())
793     }
794 }
795
796 #[stable(feature = "rust1", since = "1.0.0")]
797 impl PartialEq<str> for OsStr {
798     fn eq(&self, other: &str) -> bool {
799         *self == *OsStr::new(other)
800     }
801 }
802
803 #[stable(feature = "rust1", since = "1.0.0")]
804 impl PartialEq<OsStr> for str {
805     fn eq(&self, other: &OsStr) -> bool {
806         *other == *OsStr::new(self)
807     }
808 }
809
810 #[stable(feature = "rust1", since = "1.0.0")]
811 impl Eq for OsStr {}
812
813 #[stable(feature = "rust1", since = "1.0.0")]
814 impl PartialOrd for OsStr {
815     #[inline]
816     fn partial_cmp(&self, other: &OsStr) -> Option<cmp::Ordering> {
817         self.bytes().partial_cmp(other.bytes())
818     }
819     #[inline]
820     fn lt(&self, other: &OsStr) -> bool { self.bytes().lt(other.bytes()) }
821     #[inline]
822     fn le(&self, other: &OsStr) -> bool { self.bytes().le(other.bytes()) }
823     #[inline]
824     fn gt(&self, other: &OsStr) -> bool { self.bytes().gt(other.bytes()) }
825     #[inline]
826     fn ge(&self, other: &OsStr) -> bool { self.bytes().ge(other.bytes()) }
827 }
828
829 #[stable(feature = "rust1", since = "1.0.0")]
830 impl PartialOrd<str> for OsStr {
831     #[inline]
832     fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
833         self.partial_cmp(OsStr::new(other))
834     }
835 }
836
837 // FIXME (#19470): cannot provide PartialOrd<OsStr> for str until we
838 // have more flexible coherence rules.
839
840 #[stable(feature = "rust1", since = "1.0.0")]
841 impl Ord for OsStr {
842     #[inline]
843     fn cmp(&self, other: &OsStr) -> cmp::Ordering { self.bytes().cmp(other.bytes()) }
844 }
845
846 macro_rules! impl_cmp {
847     ($lhs:ty, $rhs: ty) => {
848         #[stable(feature = "cmp_os_str", since = "1.8.0")]
849         impl<'a, 'b> PartialEq<$rhs> for $lhs {
850             #[inline]
851             fn eq(&self, other: &$rhs) -> bool { <OsStr as PartialEq>::eq(self, other) }
852         }
853
854         #[stable(feature = "cmp_os_str", since = "1.8.0")]
855         impl<'a, 'b> PartialEq<$lhs> for $rhs {
856             #[inline]
857             fn eq(&self, other: &$lhs) -> bool { <OsStr as PartialEq>::eq(self, other) }
858         }
859
860         #[stable(feature = "cmp_os_str", since = "1.8.0")]
861         impl<'a, 'b> PartialOrd<$rhs> for $lhs {
862             #[inline]
863             fn partial_cmp(&self, other: &$rhs) -> Option<cmp::Ordering> {
864                 <OsStr as PartialOrd>::partial_cmp(self, other)
865             }
866         }
867
868         #[stable(feature = "cmp_os_str", since = "1.8.0")]
869         impl<'a, 'b> PartialOrd<$lhs> for $rhs {
870             #[inline]
871             fn partial_cmp(&self, other: &$lhs) -> Option<cmp::Ordering> {
872                 <OsStr as PartialOrd>::partial_cmp(self, other)
873             }
874         }
875     }
876 }
877
878 impl_cmp!(OsString, OsStr);
879 impl_cmp!(OsString, &'a OsStr);
880 impl_cmp!(Cow<'a, OsStr>, OsStr);
881 impl_cmp!(Cow<'a, OsStr>, &'b OsStr);
882 impl_cmp!(Cow<'a, OsStr>, OsString);
883
884 #[stable(feature = "rust1", since = "1.0.0")]
885 impl Hash for OsStr {
886     #[inline]
887     fn hash<H: Hasher>(&self, state: &mut H) {
888         self.bytes().hash(state)
889     }
890 }
891
892 #[stable(feature = "rust1", since = "1.0.0")]
893 impl fmt::Debug for OsStr {
894     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
895         fmt::Debug::fmt(&self.inner, formatter)
896     }
897 }
898
899 impl OsStr {
900     pub(crate) fn display(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
901         fmt::Display::fmt(&self.inner, formatter)
902     }
903 }
904
905 #[stable(feature = "rust1", since = "1.0.0")]
906 impl Borrow<OsStr> for OsString {
907     fn borrow(&self) -> &OsStr { &self[..] }
908 }
909
910 #[stable(feature = "rust1", since = "1.0.0")]
911 impl ToOwned for OsStr {
912     type Owned = OsString;
913     fn to_owned(&self) -> OsString {
914         self.to_os_string()
915     }
916     fn clone_into(&self, target: &mut OsString) {
917         target.clear();
918         target.push(self);
919     }
920 }
921
922 #[stable(feature = "rust1", since = "1.0.0")]
923 impl AsRef<OsStr> for OsStr {
924     fn as_ref(&self) -> &OsStr {
925         self
926     }
927 }
928
929 #[stable(feature = "rust1", since = "1.0.0")]
930 impl AsRef<OsStr> for OsString {
931     fn as_ref(&self) -> &OsStr {
932         self
933     }
934 }
935
936 #[stable(feature = "rust1", since = "1.0.0")]
937 impl AsRef<OsStr> for str {
938     fn as_ref(&self) -> &OsStr {
939         OsStr::from_inner(Slice::from_str(self))
940     }
941 }
942
943 #[stable(feature = "rust1", since = "1.0.0")]
944 impl AsRef<OsStr> for String {
945     fn as_ref(&self) -> &OsStr {
946         (&**self).as_ref()
947     }
948 }
949
950 impl FromInner<Buf> for OsString {
951     fn from_inner(buf: Buf) -> OsString {
952         OsString { inner: buf }
953     }
954 }
955
956 impl IntoInner<Buf> for OsString {
957     fn into_inner(self) -> Buf {
958         self.inner
959     }
960 }
961
962 impl AsInner<Slice> for OsStr {
963     fn as_inner(&self) -> &Slice {
964         &self.inner
965     }
966 }
967
968 #[cfg(test)]
969 mod tests {
970     use super::*;
971     use sys_common::{AsInner, IntoInner};
972
973     use rc::Rc;
974     use sync::Arc;
975
976     #[test]
977     fn test_os_string_with_capacity() {
978         let os_string = OsString::with_capacity(0);
979         assert_eq!(0, os_string.inner.into_inner().capacity());
980
981         let os_string = OsString::with_capacity(10);
982         assert_eq!(10, os_string.inner.into_inner().capacity());
983
984         let mut os_string = OsString::with_capacity(0);
985         os_string.push("abc");
986         assert!(os_string.inner.into_inner().capacity() >= 3);
987     }
988
989     #[test]
990     fn test_os_string_clear() {
991         let mut os_string = OsString::from("abc");
992         assert_eq!(3, os_string.inner.as_inner().len());
993
994         os_string.clear();
995         assert_eq!(&os_string, "");
996         assert_eq!(0, os_string.inner.as_inner().len());
997     }
998
999     #[test]
1000     fn test_os_string_capacity() {
1001         let os_string = OsString::with_capacity(0);
1002         assert_eq!(0, os_string.capacity());
1003
1004         let os_string = OsString::with_capacity(10);
1005         assert_eq!(10, os_string.capacity());
1006
1007         let mut os_string = OsString::with_capacity(0);
1008         os_string.push("abc");
1009         assert!(os_string.capacity() >= 3);
1010     }
1011
1012     #[test]
1013     fn test_os_string_reserve() {
1014         let mut os_string = OsString::new();
1015         assert_eq!(os_string.capacity(), 0);
1016
1017         os_string.reserve(2);
1018         assert!(os_string.capacity() >= 2);
1019
1020         for _ in 0..16 {
1021             os_string.push("a");
1022         }
1023
1024         assert!(os_string.capacity() >= 16);
1025         os_string.reserve(16);
1026         assert!(os_string.capacity() >= 32);
1027
1028         os_string.push("a");
1029
1030         os_string.reserve(16);
1031         assert!(os_string.capacity() >= 33)
1032     }
1033
1034     #[test]
1035     fn test_os_string_reserve_exact() {
1036         let mut os_string = OsString::new();
1037         assert_eq!(os_string.capacity(), 0);
1038
1039         os_string.reserve_exact(2);
1040         assert!(os_string.capacity() >= 2);
1041
1042         for _ in 0..16 {
1043             os_string.push("a");
1044         }
1045
1046         assert!(os_string.capacity() >= 16);
1047         os_string.reserve_exact(16);
1048         assert!(os_string.capacity() >= 32);
1049
1050         os_string.push("a");
1051
1052         os_string.reserve_exact(16);
1053         assert!(os_string.capacity() >= 33)
1054     }
1055
1056     #[test]
1057     fn test_os_string_default() {
1058         let os_string: OsString = Default::default();
1059         assert_eq!("", &os_string);
1060     }
1061
1062     #[test]
1063     fn test_os_str_is_empty() {
1064         let mut os_string = OsString::new();
1065         assert!(os_string.is_empty());
1066
1067         os_string.push("abc");
1068         assert!(!os_string.is_empty());
1069
1070         os_string.clear();
1071         assert!(os_string.is_empty());
1072     }
1073
1074     #[test]
1075     fn test_os_str_len() {
1076         let mut os_string = OsString::new();
1077         assert_eq!(0, os_string.len());
1078
1079         os_string.push("abc");
1080         assert_eq!(3, os_string.len());
1081
1082         os_string.clear();
1083         assert_eq!(0, os_string.len());
1084     }
1085
1086     #[test]
1087     fn test_os_str_default() {
1088         let os_str: &OsStr = Default::default();
1089         assert_eq!("", os_str);
1090     }
1091
1092     #[test]
1093     fn into_boxed() {
1094         let orig = "Hello, world!";
1095         let os_str = OsStr::new(orig);
1096         let boxed: Box<OsStr> = Box::from(os_str);
1097         let os_string = os_str.to_owned().into_boxed_os_str().into_os_string();
1098         assert_eq!(os_str, &*boxed);
1099         assert_eq!(&*boxed, &*os_string);
1100         assert_eq!(&*os_string, os_str);
1101     }
1102
1103     #[test]
1104     fn boxed_default() {
1105         let boxed = <Box<OsStr>>::default();
1106         assert!(boxed.is_empty());
1107     }
1108
1109     #[test]
1110     fn test_os_str_clone_into() {
1111         let mut os_string = OsString::with_capacity(123);
1112         os_string.push("hello");
1113         let os_str = OsStr::new("bonjour");
1114         os_str.clone_into(&mut os_string);
1115         assert_eq!(os_str, os_string);
1116         assert!(os_string.capacity() >= 123);
1117     }
1118
1119     #[test]
1120     fn into_rc() {
1121         let orig = "Hello, world!";
1122         let os_str = OsStr::new(orig);
1123         let rc: Rc<OsStr> = Rc::from(os_str);
1124         let arc: Arc<OsStr> = Arc::from(os_str);
1125
1126         assert_eq!(&*rc, os_str);
1127         assert_eq!(&*arc, os_str);
1128
1129         let rc2: Rc<OsStr> = Rc::from(os_str.to_owned());
1130         let arc2: Arc<OsStr> = Arc::from(os_str.to_owned());
1131
1132         assert_eq!(&*rc2, os_str);
1133         assert_eq!(&*arc2, os_str);
1134     }
1135 }