]> git.lizzy.rs Git - rust.git/blob - src/libstd/ffi/os_str.rs
Rollup merge of #60959 - petrochenkov:sassert, r=estebank
[rust.git] / src / libstd / ffi / os_str.rs
1 use crate::borrow::{Borrow, Cow};
2 use crate::fmt;
3 use crate::ops;
4 use crate::cmp;
5 use crate::hash::{Hash, Hasher};
6 use crate::rc::Rc;
7 use crate::sync::Arc;
8
9 use crate::sys::os_str::{Buf, Slice};
10 use crate::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     ///
355     /// [`OsString`]: ../../std/ffi/struct.OsString.html
356     fn from(s: String) -> OsString {
357         OsString { inner: Buf::from_string(s) }
358     }
359 }
360
361 #[stable(feature = "rust1", since = "1.0.0")]
362 impl<T: ?Sized + AsRef<OsStr>> From<&T> for OsString {
363     fn from(s: &T) -> OsString {
364         s.as_ref().to_os_string()
365     }
366 }
367
368 #[stable(feature = "rust1", since = "1.0.0")]
369 impl ops::Index<ops::RangeFull> for OsString {
370     type Output = OsStr;
371
372     #[inline]
373     fn index(&self, _index: ops::RangeFull) -> &OsStr {
374         OsStr::from_inner(self.inner.as_slice())
375     }
376 }
377
378 #[stable(feature = "rust1", since = "1.0.0")]
379 impl ops::Deref for OsString {
380     type Target = OsStr;
381
382     #[inline]
383     fn deref(&self) -> &OsStr {
384         &self[..]
385     }
386 }
387
388 #[stable(feature = "osstring_default", since = "1.9.0")]
389 impl Default for OsString {
390     /// Constructs an empty `OsString`.
391     #[inline]
392     fn default() -> OsString {
393         OsString::new()
394     }
395 }
396
397 #[stable(feature = "rust1", since = "1.0.0")]
398 impl fmt::Debug for OsString {
399     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
400         fmt::Debug::fmt(&**self, formatter)
401     }
402 }
403
404 #[stable(feature = "rust1", since = "1.0.0")]
405 impl PartialEq for OsString {
406     fn eq(&self, other: &OsString) -> bool {
407         &**self == &**other
408     }
409 }
410
411 #[stable(feature = "rust1", since = "1.0.0")]
412 impl PartialEq<str> for OsString {
413     fn eq(&self, other: &str) -> bool {
414         &**self == other
415     }
416 }
417
418 #[stable(feature = "rust1", since = "1.0.0")]
419 impl PartialEq<OsString> for str {
420     fn eq(&self, other: &OsString) -> bool {
421         &**other == self
422     }
423 }
424
425 #[stable(feature = "os_str_str_ref_eq", since = "1.29.0")]
426 impl PartialEq<&str> for OsString {
427     fn eq(&self, other: &&str) -> bool {
428         **self == **other
429     }
430 }
431
432 #[stable(feature = "os_str_str_ref_eq", since = "1.29.0")]
433 impl<'a> PartialEq<OsString> for &'a str {
434     fn eq(&self, other: &OsString) -> bool {
435         **other == **self
436     }
437 }
438
439 #[stable(feature = "rust1", since = "1.0.0")]
440 impl Eq for OsString {}
441
442 #[stable(feature = "rust1", since = "1.0.0")]
443 impl PartialOrd for OsString {
444     #[inline]
445     fn partial_cmp(&self, other: &OsString) -> Option<cmp::Ordering> {
446         (&**self).partial_cmp(&**other)
447     }
448     #[inline]
449     fn lt(&self, other: &OsString) -> bool { &**self < &**other }
450     #[inline]
451     fn le(&self, other: &OsString) -> bool { &**self <= &**other }
452     #[inline]
453     fn gt(&self, other: &OsString) -> bool { &**self > &**other }
454     #[inline]
455     fn ge(&self, other: &OsString) -> bool { &**self >= &**other }
456 }
457
458 #[stable(feature = "rust1", since = "1.0.0")]
459 impl PartialOrd<str> for OsString {
460     #[inline]
461     fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
462         (&**self).partial_cmp(other)
463     }
464 }
465
466 #[stable(feature = "rust1", since = "1.0.0")]
467 impl Ord for OsString {
468     #[inline]
469     fn cmp(&self, other: &OsString) -> cmp::Ordering {
470         (&**self).cmp(&**other)
471     }
472 }
473
474 #[stable(feature = "rust1", since = "1.0.0")]
475 impl Hash for OsString {
476     #[inline]
477     fn hash<H: Hasher>(&self, state: &mut H) {
478         (&**self).hash(state)
479     }
480 }
481
482 impl OsStr {
483     /// Coerces into an `OsStr` slice.
484     ///
485     /// # Examples
486     ///
487     /// ```
488     /// use std::ffi::OsStr;
489     ///
490     /// let os_str = OsStr::new("foo");
491     /// ```
492     #[stable(feature = "rust1", since = "1.0.0")]
493     pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &OsStr {
494         s.as_ref()
495     }
496
497     fn from_inner(inner: &Slice) -> &OsStr {
498         unsafe { &*(inner as *const Slice as *const OsStr) }
499     }
500
501     /// Yields a [`&str`] slice if the `OsStr` is valid Unicode.
502     ///
503     /// This conversion may entail doing a check for UTF-8 validity.
504     ///
505     /// [`&str`]: ../../std/primitive.str.html
506     ///
507     /// # Examples
508     ///
509     /// ```
510     /// use std::ffi::OsStr;
511     ///
512     /// let os_str = OsStr::new("foo");
513     /// assert_eq!(os_str.to_str(), Some("foo"));
514     /// ```
515     #[stable(feature = "rust1", since = "1.0.0")]
516     pub fn to_str(&self) -> Option<&str> {
517         self.inner.to_str()
518     }
519
520     /// Converts an `OsStr` to a [`Cow`]`<`[`str`]`>`.
521     ///
522     /// Any non-Unicode sequences are replaced with
523     /// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD].
524     ///
525     /// [`Cow`]: ../../std/borrow/enum.Cow.html
526     /// [`str`]: ../../std/primitive.str.html
527     /// [U+FFFD]: ../../std/char/constant.REPLACEMENT_CHARACTER.html
528     ///
529     /// # Examples
530     ///
531     /// Calling `to_string_lossy` on an `OsStr` with invalid unicode:
532     ///
533     /// ```
534     /// // Note, due to differences in how Unix and Windows represent strings,
535     /// // we are forced to complicate this example, setting up example `OsStr`s
536     /// // with different source data and via different platform extensions.
537     /// // Understand that in reality you could end up with such example invalid
538     /// // sequences simply through collecting user command line arguments, for
539     /// // example.
540     ///
541     /// #[cfg(any(unix, target_os = "redox"))] {
542     ///     use std::ffi::OsStr;
543     ///     use std::os::unix::ffi::OsStrExt;
544     ///
545     ///     // Here, the values 0x66 and 0x6f correspond to 'f' and 'o'
546     ///     // respectively. The value 0x80 is a lone continuation byte, invalid
547     ///     // in a UTF-8 sequence.
548     ///     let source = [0x66, 0x6f, 0x80, 0x6f];
549     ///     let os_str = OsStr::from_bytes(&source[..]);
550     ///
551     ///     assert_eq!(os_str.to_string_lossy(), "fo�o");
552     /// }
553     /// #[cfg(windows)] {
554     ///     use std::ffi::OsString;
555     ///     use std::os::windows::prelude::*;
556     ///
557     ///     // Here the values 0x0066 and 0x006f correspond to 'f' and 'o'
558     ///     // respectively. The value 0xD800 is a lone surrogate half, invalid
559     ///     // in a UTF-16 sequence.
560     ///     let source = [0x0066, 0x006f, 0xD800, 0x006f];
561     ///     let os_string = OsString::from_wide(&source[..]);
562     ///     let os_str = os_string.as_os_str();
563     ///
564     ///     assert_eq!(os_str.to_string_lossy(), "fo�o");
565     /// }
566     /// ```
567     #[stable(feature = "rust1", since = "1.0.0")]
568     pub fn to_string_lossy(&self) -> Cow<'_, str> {
569         self.inner.to_string_lossy()
570     }
571
572     /// Copies the slice into an owned [`OsString`].
573     ///
574     /// [`OsString`]: struct.OsString.html
575     ///
576     /// # Examples
577     ///
578     /// ```
579     /// use std::ffi::{OsStr, OsString};
580     ///
581     /// let os_str = OsStr::new("foo");
582     /// let os_string = os_str.to_os_string();
583     /// assert_eq!(os_string, OsString::from("foo"));
584     /// ```
585     #[stable(feature = "rust1", since = "1.0.0")]
586     pub fn to_os_string(&self) -> OsString {
587         OsString { inner: self.inner.to_owned() }
588     }
589
590     /// Checks whether the `OsStr` is empty.
591     ///
592     /// # Examples
593     ///
594     /// ```
595     /// use std::ffi::OsStr;
596     ///
597     /// let os_str = OsStr::new("");
598     /// assert!(os_str.is_empty());
599     ///
600     /// let os_str = OsStr::new("foo");
601     /// assert!(!os_str.is_empty());
602     /// ```
603     #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
604     pub fn is_empty(&self) -> bool {
605         self.inner.inner.is_empty()
606     }
607
608     /// Returns the length of this `OsStr`.
609     ///
610     /// Note that this does **not** return the number of bytes in the string in
611     /// OS string form.
612     ///
613     /// The length returned is that of the underlying storage used by `OsStr`;
614     /// As discussed in the [`OsString`] introduction, [`OsString`] and `OsStr`
615     /// store strings in a form best suited for cheap inter-conversion between
616     /// native-platform and Rust string forms, which may differ significantly
617     /// from both of them, including in storage size and encoding.
618     ///
619     /// This number is simply useful for passing to other methods, like
620     /// [`OsString::with_capacity`] to avoid reallocations.
621     ///
622     /// [`OsString`]: struct.OsString.html
623     /// [`OsString::with_capacity`]: struct.OsString.html#method.with_capacity
624     ///
625     /// # Examples
626     ///
627     /// ```
628     /// use std::ffi::OsStr;
629     ///
630     /// let os_str = OsStr::new("");
631     /// assert_eq!(os_str.len(), 0);
632     ///
633     /// let os_str = OsStr::new("foo");
634     /// assert_eq!(os_str.len(), 3);
635     /// ```
636     #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
637     pub fn len(&self) -> usize {
638         self.inner.inner.len()
639     }
640
641     /// Converts a [`Box`]`<OsStr>` into an [`OsString`] without copying or allocating.
642     ///
643     /// [`Box`]: ../boxed/struct.Box.html
644     /// [`OsString`]: struct.OsString.html
645     #[stable(feature = "into_boxed_os_str", since = "1.20.0")]
646     pub fn into_os_string(self: Box<OsStr>) -> OsString {
647         let boxed = unsafe { Box::from_raw(Box::into_raw(self) as *mut Slice) };
648         OsString { inner: Buf::from_box(boxed) }
649     }
650
651     /// Gets the underlying byte representation.
652     ///
653     /// Note: it is *crucial* that this API is private, to avoid
654     /// revealing the internal, platform-specific encodings.
655     fn bytes(&self) -> &[u8] {
656         unsafe { &*(&self.inner as *const _ as *const [u8]) }
657     }
658 }
659
660 #[stable(feature = "box_from_os_str", since = "1.17.0")]
661 impl From<&OsStr> for Box<OsStr> {
662     fn from(s: &OsStr) -> Box<OsStr> {
663         let rw = Box::into_raw(s.inner.into_box()) as *mut OsStr;
664         unsafe { Box::from_raw(rw) }
665     }
666 }
667
668 #[stable(feature = "os_string_from_box", since = "1.18.0")]
669 impl From<Box<OsStr>> for OsString {
670     /// Converts a `Box<OsStr>` into a `OsString` without copying or allocating.
671     ///
672     /// [`Box`]: ../boxed/struct.Box.html
673     /// [`OsString`]: ../ffi/struct.OsString.html
674     fn from(boxed: Box<OsStr>) -> OsString {
675         boxed.into_os_string()
676     }
677 }
678
679 #[stable(feature = "box_from_os_string", since = "1.20.0")]
680 impl From<OsString> for Box<OsStr> {
681     /// Converts a [`OsString`] into a [`Box`]`<OsStr>` without copying or allocating.
682     ///
683     /// [`Box`]: ../boxed/struct.Box.html
684     /// [`OsString`]: ../ffi/struct.OsString.html
685     fn from(s: OsString) -> Box<OsStr> {
686         s.into_boxed_os_str()
687     }
688 }
689
690 #[stable(feature = "more_box_slice_clone", since = "1.29.0")]
691 impl Clone for Box<OsStr> {
692     #[inline]
693     fn clone(&self) -> Self {
694         self.to_os_string().into_boxed_os_str()
695     }
696 }
697
698 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
699 impl From<OsString> for Arc<OsStr> {
700     /// Converts a [`OsString`] into a [`Arc`]`<OsStr>` without copying or allocating.
701     ///
702     /// [`Arc`]: ../sync/struct.Arc.html
703     /// [`OsString`]: ../ffi/struct.OsString.html
704     #[inline]
705     fn from(s: OsString) -> Arc<OsStr> {
706         let arc = s.inner.into_arc();
707         unsafe { Arc::from_raw(Arc::into_raw(arc) as *const OsStr) }
708     }
709 }
710
711 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
712 impl From<&OsStr> for Arc<OsStr> {
713     #[inline]
714     fn from(s: &OsStr) -> Arc<OsStr> {
715         let arc = s.inner.into_arc();
716         unsafe { Arc::from_raw(Arc::into_raw(arc) as *const OsStr) }
717     }
718 }
719
720 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
721 impl From<OsString> for Rc<OsStr> {
722     /// Converts a [`OsString`] into a [`Rc`]`<OsStr>` without copying or allocating.
723     ///
724     /// [`Rc`]: ../rc/struct.Rc.html
725     /// [`OsString`]: ../ffi/struct.OsString.html
726     #[inline]
727     fn from(s: OsString) -> Rc<OsStr> {
728         let rc = s.inner.into_rc();
729         unsafe { Rc::from_raw(Rc::into_raw(rc) as *const OsStr) }
730     }
731 }
732
733 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
734 impl From<&OsStr> for Rc<OsStr> {
735     #[inline]
736     fn from(s: &OsStr) -> Rc<OsStr> {
737         let rc = s.inner.into_rc();
738         unsafe { Rc::from_raw(Rc::into_raw(rc) as *const OsStr) }
739     }
740 }
741
742 #[stable(feature = "cow_from_osstr", since = "1.28.0")]
743 impl<'a> From<OsString> for Cow<'a, OsStr> {
744     #[inline]
745     fn from(s: OsString) -> Cow<'a, OsStr> {
746         Cow::Owned(s)
747     }
748 }
749
750 #[stable(feature = "cow_from_osstr", since = "1.28.0")]
751 impl<'a> From<&'a OsStr> for Cow<'a, OsStr> {
752     #[inline]
753     fn from(s: &'a OsStr) -> Cow<'a, OsStr> {
754         Cow::Borrowed(s)
755     }
756 }
757
758 #[stable(feature = "cow_from_osstr", since = "1.28.0")]
759 impl<'a> From<&'a OsString> for Cow<'a, OsStr> {
760     #[inline]
761     fn from(s: &'a OsString) -> Cow<'a, OsStr> {
762         Cow::Borrowed(s.as_os_str())
763     }
764 }
765
766 #[stable(feature = "osstring_from_cow_osstr", since = "1.28.0")]
767 impl<'a> From<Cow<'a, OsStr>> for OsString {
768     #[inline]
769     fn from(s: Cow<'a, OsStr>) -> Self {
770         s.into_owned()
771     }
772 }
773
774 #[stable(feature = "box_default_extra", since = "1.17.0")]
775 impl Default for Box<OsStr> {
776     fn default() -> Box<OsStr> {
777         let rw = Box::into_raw(Slice::empty_box()) as *mut OsStr;
778         unsafe { Box::from_raw(rw) }
779     }
780 }
781
782 #[stable(feature = "osstring_default", since = "1.9.0")]
783 impl Default for &OsStr {
784     /// Creates an empty `OsStr`.
785     #[inline]
786     fn default() -> Self {
787         OsStr::new("")
788     }
789 }
790
791 #[stable(feature = "rust1", since = "1.0.0")]
792 impl PartialEq for OsStr {
793     fn eq(&self, other: &OsStr) -> bool {
794         self.bytes().eq(other.bytes())
795     }
796 }
797
798 #[stable(feature = "rust1", since = "1.0.0")]
799 impl PartialEq<str> for OsStr {
800     fn eq(&self, other: &str) -> bool {
801         *self == *OsStr::new(other)
802     }
803 }
804
805 #[stable(feature = "rust1", since = "1.0.0")]
806 impl PartialEq<OsStr> for str {
807     fn eq(&self, other: &OsStr) -> bool {
808         *other == *OsStr::new(self)
809     }
810 }
811
812 #[stable(feature = "rust1", since = "1.0.0")]
813 impl Eq for OsStr {}
814
815 #[stable(feature = "rust1", since = "1.0.0")]
816 impl PartialOrd for OsStr {
817     #[inline]
818     fn partial_cmp(&self, other: &OsStr) -> Option<cmp::Ordering> {
819         self.bytes().partial_cmp(other.bytes())
820     }
821     #[inline]
822     fn lt(&self, other: &OsStr) -> bool { self.bytes().lt(other.bytes()) }
823     #[inline]
824     fn le(&self, other: &OsStr) -> bool { self.bytes().le(other.bytes()) }
825     #[inline]
826     fn gt(&self, other: &OsStr) -> bool { self.bytes().gt(other.bytes()) }
827     #[inline]
828     fn ge(&self, other: &OsStr) -> bool { self.bytes().ge(other.bytes()) }
829 }
830
831 #[stable(feature = "rust1", since = "1.0.0")]
832 impl PartialOrd<str> for OsStr {
833     #[inline]
834     fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
835         self.partial_cmp(OsStr::new(other))
836     }
837 }
838
839 // FIXME (#19470): cannot provide PartialOrd<OsStr> for str until we
840 // have more flexible coherence rules.
841
842 #[stable(feature = "rust1", since = "1.0.0")]
843 impl Ord for OsStr {
844     #[inline]
845     fn cmp(&self, other: &OsStr) -> cmp::Ordering { self.bytes().cmp(other.bytes()) }
846 }
847
848 macro_rules! impl_cmp {
849     ($lhs:ty, $rhs: ty) => {
850         #[stable(feature = "cmp_os_str", since = "1.8.0")]
851         impl<'a, 'b> PartialEq<$rhs> for $lhs {
852             #[inline]
853             fn eq(&self, other: &$rhs) -> bool { <OsStr as PartialEq>::eq(self, other) }
854         }
855
856         #[stable(feature = "cmp_os_str", since = "1.8.0")]
857         impl<'a, 'b> PartialEq<$lhs> for $rhs {
858             #[inline]
859             fn eq(&self, other: &$lhs) -> bool { <OsStr as PartialEq>::eq(self, other) }
860         }
861
862         #[stable(feature = "cmp_os_str", since = "1.8.0")]
863         impl<'a, 'b> PartialOrd<$rhs> for $lhs {
864             #[inline]
865             fn partial_cmp(&self, other: &$rhs) -> Option<cmp::Ordering> {
866                 <OsStr as PartialOrd>::partial_cmp(self, other)
867             }
868         }
869
870         #[stable(feature = "cmp_os_str", since = "1.8.0")]
871         impl<'a, 'b> PartialOrd<$lhs> for $rhs {
872             #[inline]
873             fn partial_cmp(&self, other: &$lhs) -> Option<cmp::Ordering> {
874                 <OsStr as PartialOrd>::partial_cmp(self, other)
875             }
876         }
877     }
878 }
879
880 impl_cmp!(OsString, OsStr);
881 impl_cmp!(OsString, &'a OsStr);
882 impl_cmp!(Cow<'a, OsStr>, OsStr);
883 impl_cmp!(Cow<'a, OsStr>, &'b OsStr);
884 impl_cmp!(Cow<'a, OsStr>, OsString);
885
886 #[stable(feature = "rust1", since = "1.0.0")]
887 impl Hash for OsStr {
888     #[inline]
889     fn hash<H: Hasher>(&self, state: &mut H) {
890         self.bytes().hash(state)
891     }
892 }
893
894 #[stable(feature = "rust1", since = "1.0.0")]
895 impl fmt::Debug for OsStr {
896     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
897         fmt::Debug::fmt(&self.inner, formatter)
898     }
899 }
900
901 impl OsStr {
902     pub(crate) fn display(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
903         fmt::Display::fmt(&self.inner, formatter)
904     }
905 }
906
907 #[stable(feature = "rust1", since = "1.0.0")]
908 impl Borrow<OsStr> for OsString {
909     fn borrow(&self) -> &OsStr { &self[..] }
910 }
911
912 #[stable(feature = "rust1", since = "1.0.0")]
913 impl ToOwned for OsStr {
914     type Owned = OsString;
915     fn to_owned(&self) -> OsString {
916         self.to_os_string()
917     }
918     fn clone_into(&self, target: &mut OsString) {
919         target.clear();
920         target.push(self);
921     }
922 }
923
924 #[stable(feature = "rust1", since = "1.0.0")]
925 impl AsRef<OsStr> for OsStr {
926     fn as_ref(&self) -> &OsStr {
927         self
928     }
929 }
930
931 #[stable(feature = "rust1", since = "1.0.0")]
932 impl AsRef<OsStr> for OsString {
933     fn as_ref(&self) -> &OsStr {
934         self
935     }
936 }
937
938 #[stable(feature = "rust1", since = "1.0.0")]
939 impl AsRef<OsStr> for str {
940     fn as_ref(&self) -> &OsStr {
941         OsStr::from_inner(Slice::from_str(self))
942     }
943 }
944
945 #[stable(feature = "rust1", since = "1.0.0")]
946 impl AsRef<OsStr> for String {
947     fn as_ref(&self) -> &OsStr {
948         (&**self).as_ref()
949     }
950 }
951
952 impl FromInner<Buf> for OsString {
953     fn from_inner(buf: Buf) -> OsString {
954         OsString { inner: buf }
955     }
956 }
957
958 impl IntoInner<Buf> for OsString {
959     fn into_inner(self) -> Buf {
960         self.inner
961     }
962 }
963
964 impl AsInner<Slice> for OsStr {
965     #[inline]
966     fn as_inner(&self) -> &Slice {
967         &self.inner
968     }
969 }
970
971 #[cfg(test)]
972 mod tests {
973     use super::*;
974     use crate::sys_common::{AsInner, IntoInner};
975
976     use crate::rc::Rc;
977     use crate::sync::Arc;
978
979     #[test]
980     fn test_os_string_with_capacity() {
981         let os_string = OsString::with_capacity(0);
982         assert_eq!(0, os_string.inner.into_inner().capacity());
983
984         let os_string = OsString::with_capacity(10);
985         assert_eq!(10, os_string.inner.into_inner().capacity());
986
987         let mut os_string = OsString::with_capacity(0);
988         os_string.push("abc");
989         assert!(os_string.inner.into_inner().capacity() >= 3);
990     }
991
992     #[test]
993     fn test_os_string_clear() {
994         let mut os_string = OsString::from("abc");
995         assert_eq!(3, os_string.inner.as_inner().len());
996
997         os_string.clear();
998         assert_eq!(&os_string, "");
999         assert_eq!(0, os_string.inner.as_inner().len());
1000     }
1001
1002     #[test]
1003     fn test_os_string_capacity() {
1004         let os_string = OsString::with_capacity(0);
1005         assert_eq!(0, os_string.capacity());
1006
1007         let os_string = OsString::with_capacity(10);
1008         assert_eq!(10, os_string.capacity());
1009
1010         let mut os_string = OsString::with_capacity(0);
1011         os_string.push("abc");
1012         assert!(os_string.capacity() >= 3);
1013     }
1014
1015     #[test]
1016     fn test_os_string_reserve() {
1017         let mut os_string = OsString::new();
1018         assert_eq!(os_string.capacity(), 0);
1019
1020         os_string.reserve(2);
1021         assert!(os_string.capacity() >= 2);
1022
1023         for _ in 0..16 {
1024             os_string.push("a");
1025         }
1026
1027         assert!(os_string.capacity() >= 16);
1028         os_string.reserve(16);
1029         assert!(os_string.capacity() >= 32);
1030
1031         os_string.push("a");
1032
1033         os_string.reserve(16);
1034         assert!(os_string.capacity() >= 33)
1035     }
1036
1037     #[test]
1038     fn test_os_string_reserve_exact() {
1039         let mut os_string = OsString::new();
1040         assert_eq!(os_string.capacity(), 0);
1041
1042         os_string.reserve_exact(2);
1043         assert!(os_string.capacity() >= 2);
1044
1045         for _ in 0..16 {
1046             os_string.push("a");
1047         }
1048
1049         assert!(os_string.capacity() >= 16);
1050         os_string.reserve_exact(16);
1051         assert!(os_string.capacity() >= 32);
1052
1053         os_string.push("a");
1054
1055         os_string.reserve_exact(16);
1056         assert!(os_string.capacity() >= 33)
1057     }
1058
1059     #[test]
1060     fn test_os_string_default() {
1061         let os_string: OsString = Default::default();
1062         assert_eq!("", &os_string);
1063     }
1064
1065     #[test]
1066     fn test_os_str_is_empty() {
1067         let mut os_string = OsString::new();
1068         assert!(os_string.is_empty());
1069
1070         os_string.push("abc");
1071         assert!(!os_string.is_empty());
1072
1073         os_string.clear();
1074         assert!(os_string.is_empty());
1075     }
1076
1077     #[test]
1078     fn test_os_str_len() {
1079         let mut os_string = OsString::new();
1080         assert_eq!(0, os_string.len());
1081
1082         os_string.push("abc");
1083         assert_eq!(3, os_string.len());
1084
1085         os_string.clear();
1086         assert_eq!(0, os_string.len());
1087     }
1088
1089     #[test]
1090     fn test_os_str_default() {
1091         let os_str: &OsStr = Default::default();
1092         assert_eq!("", os_str);
1093     }
1094
1095     #[test]
1096     fn into_boxed() {
1097         let orig = "Hello, world!";
1098         let os_str = OsStr::new(orig);
1099         let boxed: Box<OsStr> = Box::from(os_str);
1100         let os_string = os_str.to_owned().into_boxed_os_str().into_os_string();
1101         assert_eq!(os_str, &*boxed);
1102         assert_eq!(&*boxed, &*os_string);
1103         assert_eq!(&*os_string, os_str);
1104     }
1105
1106     #[test]
1107     fn boxed_default() {
1108         let boxed = <Box<OsStr>>::default();
1109         assert!(boxed.is_empty());
1110     }
1111
1112     #[test]
1113     fn test_os_str_clone_into() {
1114         let mut os_string = OsString::with_capacity(123);
1115         os_string.push("hello");
1116         let os_str = OsStr::new("bonjour");
1117         os_str.clone_into(&mut os_string);
1118         assert_eq!(os_str, os_string);
1119         assert!(os_string.capacity() >= 123);
1120     }
1121
1122     #[test]
1123     fn into_rc() {
1124         let orig = "Hello, world!";
1125         let os_str = OsStr::new(orig);
1126         let rc: Rc<OsStr> = Rc::from(os_str);
1127         let arc: Arc<OsStr> = Arc::from(os_str);
1128
1129         assert_eq!(&*rc, os_str);
1130         assert_eq!(&*arc, os_str);
1131
1132         let rc2: Rc<OsStr> = Rc::from(os_str.to_owned());
1133         let arc2: Arc<OsStr> = Arc::from(os_str.to_owned());
1134
1135         assert_eq!(&*rc2, os_str);
1136         assert_eq!(&*arc2, os_str);
1137     }
1138 }