4 use crate::borrow::{Borrow, Cow};
7 use crate::hash::{Hash, Hasher};
10 use crate::str::FromStr;
13 use crate::sys::os_str::{Buf, Slice};
14 use crate::sys_common::{AsInner, FromInner, IntoInner};
16 /// A type that can represent owned, mutable platform-native strings, but is
17 /// cheaply inter-convertible with Rust strings.
19 /// The need for this type arises from the fact that:
21 /// * On Unix systems, strings are often arbitrary sequences of non-zero
22 /// bytes, in many cases interpreted as UTF-8.
24 /// * On Windows, strings are often arbitrary sequences of non-zero 16-bit
25 /// values, interpreted as UTF-16 when it is valid to do so.
27 /// * In Rust, strings are always valid UTF-8, which may contain zeros.
29 /// `OsString` and [`OsStr`] bridge this gap by simultaneously representing Rust
30 /// and platform-native string values, and in particular allowing a Rust string
31 /// to be converted into an "OS" string with no cost if possible. A consequence
32 /// of this is that `OsString` instances are *not* `NUL` terminated; in order
33 /// to pass to e.g., Unix system call, you should create a [`CStr`].
35 /// `OsString` is to [`&OsStr`] as [`String`] is to [`&str`]: the former
36 /// in each pair are owned strings; the latter are borrowed
39 /// Note, `OsString` and [`OsStr`] internally do not necessarily hold strings in
40 /// the form native to the platform; While on Unix, strings are stored as a
41 /// sequence of 8-bit values, on Windows, where strings are 16-bit value based
42 /// as just discussed, strings are also actually stored as a sequence of 8-bit
43 /// values, encoded in a less-strict variant of UTF-8. This is useful to
44 /// understand when handling capacity and length values.
46 /// # Creating an `OsString`
48 /// **From a Rust string**: `OsString` implements
49 /// [`From`]`<`[`String`]`>`, so you can use `my_string.from` to
50 /// create an `OsString` from a normal Rust string.
52 /// **From slices:** Just like you can start with an empty Rust
53 /// [`String`] and then [`String::push_str`] `&str`
54 /// sub-string slices into it, you can create an empty `OsString` with
55 /// the [`OsString::new`] method and then push string slices into it with the
56 /// [`OsString::push`] method.
58 /// # Extracting a borrowed reference to the whole OS string
60 /// You can use the [`OsString::as_os_str`] method to get an `&`[`OsStr`] from
61 /// an `OsString`; this is effectively a borrowed reference to the
66 /// See the [module's toplevel documentation about conversions][conversions] for a discussion on
67 /// the traits which `OsString` implements for [conversions] from/to native representations.
71 /// [`CStr`]: crate::ffi::CStr
72 /// [conversions]: index.html#conversions
74 #[stable(feature = "rust1", since = "1.0.0")]
79 /// Borrowed reference to an OS string (see [`OsString`]).
81 /// This type represents a borrowed reference to a string in the operating system's preferred
84 /// `&OsStr` is to [`OsString`] as [`&str`] is to [`String`]: the former in each pair are borrowed
85 /// references; the latter are owned strings.
87 /// See the [module's toplevel documentation about conversions][conversions] for a discussion on
88 /// the traits which `OsStr` implements for [conversions] from/to native representations.
91 /// [conversions]: index.html#conversions
92 #[stable(feature = "rust1", since = "1.0.0")]
94 // `OsStr::from_inner` current implementation relies
95 // on `OsStr` being layout-compatible with `Slice`.
96 // When attribute privacy is implemented, `OsStr` should be annotated as `#[repr(transparent)]`.
97 // Anyway, `OsStr` representation and layout are considered implementation detail, are
98 // not documented and must not be relied upon.
104 /// Constructs a new empty `OsString`.
109 /// use std::ffi::OsString;
111 /// let os_string = OsString::new();
113 #[stable(feature = "rust1", since = "1.0.0")]
114 pub fn new() -> OsString {
115 OsString { inner: Buf::from_string(String::new()) }
118 /// Converts to an [`OsStr`] slice.
123 /// use std::ffi::{OsString, OsStr};
125 /// let os_string = OsString::from("foo");
126 /// let os_str = OsStr::new("foo");
127 /// assert_eq!(os_string.as_os_str(), os_str);
129 #[stable(feature = "rust1", since = "1.0.0")]
130 pub fn as_os_str(&self) -> &OsStr {
134 /// Converts the `OsString` into a [`String`] if it contains valid Unicode data.
136 /// On failure, ownership of the original `OsString` is returned.
141 /// use std::ffi::OsString;
143 /// let os_string = OsString::from("foo");
144 /// let string = os_string.into_string();
145 /// assert_eq!(string, Ok(String::from("foo")));
147 #[stable(feature = "rust1", since = "1.0.0")]
148 pub fn into_string(self) -> Result<String, OsString> {
149 self.inner.into_string().map_err(|buf| OsString { inner: buf })
152 /// Extends the string with the given [`&OsStr`] slice.
154 /// [`&OsStr`]: OsStr
159 /// use std::ffi::OsString;
161 /// let mut os_string = OsString::from("foo");
162 /// os_string.push("bar");
163 /// assert_eq!(&os_string, "foobar");
165 #[stable(feature = "rust1", since = "1.0.0")]
166 pub fn push<T: AsRef<OsStr>>(&mut self, s: T) {
167 self.inner.push_slice(&s.as_ref().inner)
170 /// Creates a new `OsString` with the given capacity.
172 /// The string will be able to hold exactly `capacity` length units of other
173 /// OS strings without reallocating. If `capacity` is 0, the string will not
176 /// See main `OsString` documentation information about encoding.
181 /// use std::ffi::OsString;
183 /// let mut os_string = OsString::with_capacity(10);
184 /// let capacity = os_string.capacity();
186 /// // This push is done without reallocating
187 /// os_string.push("foo");
189 /// assert_eq!(capacity, os_string.capacity());
191 #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
192 pub fn with_capacity(capacity: usize) -> OsString {
193 OsString { inner: Buf::with_capacity(capacity) }
196 /// Truncates the `OsString` to zero length.
201 /// use std::ffi::OsString;
203 /// let mut os_string = OsString::from("foo");
204 /// assert_eq!(&os_string, "foo");
206 /// os_string.clear();
207 /// assert_eq!(&os_string, "");
209 #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
210 pub fn clear(&mut self) {
214 /// Returns the capacity this `OsString` can hold without reallocating.
216 /// See `OsString` introduction for information about encoding.
221 /// use std::ffi::OsString;
223 /// let os_string = OsString::with_capacity(10);
224 /// assert!(os_string.capacity() >= 10);
226 #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
227 pub fn capacity(&self) -> usize {
228 self.inner.capacity()
231 /// Reserves capacity for at least `additional` more capacity to be inserted
232 /// in the given `OsString`.
234 /// The collection may reserve more space to avoid frequent reallocations.
239 /// use std::ffi::OsString;
241 /// let mut s = OsString::new();
243 /// assert!(s.capacity() >= 10);
245 #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
246 pub fn reserve(&mut self, additional: usize) {
247 self.inner.reserve(additional)
250 /// Reserves the minimum capacity for exactly `additional` more capacity to
251 /// be inserted in the given `OsString`. Does nothing if the capacity is
252 /// already sufficient.
254 /// Note that the allocator may give the collection more space than it
255 /// requests. Therefore, capacity can not be relied upon to be precisely
256 /// minimal. Prefer reserve if future insertions are expected.
261 /// use std::ffi::OsString;
263 /// let mut s = OsString::new();
264 /// s.reserve_exact(10);
265 /// assert!(s.capacity() >= 10);
267 #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
268 pub fn reserve_exact(&mut self, additional: usize) {
269 self.inner.reserve_exact(additional)
272 /// Shrinks the capacity of the `OsString` to match its length.
277 /// use std::ffi::OsString;
279 /// let mut s = OsString::from("foo");
282 /// assert!(s.capacity() >= 100);
284 /// s.shrink_to_fit();
285 /// assert_eq!(3, s.capacity());
287 #[stable(feature = "osstring_shrink_to_fit", since = "1.19.0")]
288 pub fn shrink_to_fit(&mut self) {
289 self.inner.shrink_to_fit()
292 /// Shrinks the capacity of the `OsString` with a lower bound.
294 /// The capacity will remain at least as large as both the length
295 /// and the supplied value.
297 /// Panics if the current capacity is smaller than the supplied
298 /// minimum capacity.
303 /// #![feature(shrink_to)]
304 /// use std::ffi::OsString;
306 /// let mut s = OsString::from("foo");
309 /// assert!(s.capacity() >= 100);
312 /// assert!(s.capacity() >= 10);
314 /// assert!(s.capacity() >= 3);
317 #[unstable(feature = "shrink_to", reason = "new API", issue = "56431")]
318 pub fn shrink_to(&mut self, min_capacity: usize) {
319 self.inner.shrink_to(min_capacity)
322 /// Converts this `OsString` into a boxed [`OsStr`].
327 /// use std::ffi::{OsString, OsStr};
329 /// let s = OsString::from("hello");
331 /// let b: Box<OsStr> = s.into_boxed_os_str();
333 #[stable(feature = "into_boxed_os_str", since = "1.20.0")]
334 pub fn into_boxed_os_str(self) -> Box<OsStr> {
335 let rw = Box::into_raw(self.inner.into_box()) as *mut OsStr;
336 unsafe { Box::from_raw(rw) }
340 #[stable(feature = "rust1", since = "1.0.0")]
341 impl From<String> for OsString {
342 /// Converts a [`String`] into a [`OsString`].
344 /// The conversion copies the data, and includes an allocation on the heap.
345 fn from(s: String) -> OsString {
346 OsString { inner: Buf::from_string(s) }
350 #[stable(feature = "rust1", since = "1.0.0")]
351 impl<T: ?Sized + AsRef<OsStr>> From<&T> for OsString {
352 fn from(s: &T) -> OsString {
353 s.as_ref().to_os_string()
357 #[stable(feature = "rust1", since = "1.0.0")]
358 impl ops::Index<ops::RangeFull> for OsString {
362 fn index(&self, _index: ops::RangeFull) -> &OsStr {
363 OsStr::from_inner(self.inner.as_slice())
367 #[stable(feature = "mut_osstr", since = "1.44.0")]
368 impl ops::IndexMut<ops::RangeFull> for OsString {
370 fn index_mut(&mut self, _index: ops::RangeFull) -> &mut OsStr {
371 OsStr::from_inner_mut(self.inner.as_mut_slice())
375 #[stable(feature = "rust1", since = "1.0.0")]
376 impl ops::Deref for OsString {
380 fn deref(&self) -> &OsStr {
385 #[stable(feature = "mut_osstr", since = "1.44.0")]
386 impl ops::DerefMut for OsString {
388 fn deref_mut(&mut self) -> &mut OsStr {
393 #[stable(feature = "osstring_default", since = "1.9.0")]
394 impl Default for OsString {
395 /// Constructs an empty `OsString`.
397 fn default() -> OsString {
402 #[stable(feature = "rust1", since = "1.0.0")]
403 impl fmt::Debug for OsString {
404 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
405 fmt::Debug::fmt(&**self, formatter)
409 #[stable(feature = "rust1", since = "1.0.0")]
410 impl PartialEq for OsString {
411 fn eq(&self, other: &OsString) -> bool {
416 #[stable(feature = "rust1", since = "1.0.0")]
417 impl PartialEq<str> for OsString {
418 fn eq(&self, other: &str) -> bool {
423 #[stable(feature = "rust1", since = "1.0.0")]
424 impl PartialEq<OsString> for str {
425 fn eq(&self, other: &OsString) -> bool {
430 #[stable(feature = "os_str_str_ref_eq", since = "1.29.0")]
431 impl PartialEq<&str> for OsString {
432 fn eq(&self, other: &&str) -> bool {
437 #[stable(feature = "os_str_str_ref_eq", since = "1.29.0")]
438 impl<'a> PartialEq<OsString> for &'a str {
439 fn eq(&self, other: &OsString) -> bool {
444 #[stable(feature = "rust1", since = "1.0.0")]
445 impl Eq for OsString {}
447 #[stable(feature = "rust1", since = "1.0.0")]
448 impl PartialOrd for OsString {
450 fn partial_cmp(&self, other: &OsString) -> Option<cmp::Ordering> {
451 (&**self).partial_cmp(&**other)
454 fn lt(&self, other: &OsString) -> bool {
458 fn le(&self, other: &OsString) -> bool {
462 fn gt(&self, other: &OsString) -> bool {
466 fn ge(&self, other: &OsString) -> bool {
471 #[stable(feature = "rust1", since = "1.0.0")]
472 impl PartialOrd<str> for OsString {
474 fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
475 (&**self).partial_cmp(other)
479 #[stable(feature = "rust1", since = "1.0.0")]
480 impl Ord for OsString {
482 fn cmp(&self, other: &OsString) -> cmp::Ordering {
483 (&**self).cmp(&**other)
487 #[stable(feature = "rust1", since = "1.0.0")]
488 impl Hash for OsString {
490 fn hash<H: Hasher>(&self, state: &mut H) {
491 (&**self).hash(state)
496 /// Coerces into an `OsStr` slice.
501 /// use std::ffi::OsStr;
503 /// let os_str = OsStr::new("foo");
506 #[stable(feature = "rust1", since = "1.0.0")]
507 pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &OsStr {
512 fn from_inner(inner: &Slice) -> &OsStr {
513 // SAFETY: OsStr is just a wrapper of Slice,
514 // therefore converting &Slice to &OsStr is safe.
515 unsafe { &*(inner as *const Slice as *const OsStr) }
519 fn from_inner_mut(inner: &mut Slice) -> &mut OsStr {
520 // SAFETY: OsStr is just a wrapper of Slice,
521 // therefore converting &mut Slice to &mut OsStr is safe.
522 // Any method that mutates OsStr must be careful not to
523 // break platform-specific encoding, in particular Wtf8 on Windows.
524 unsafe { &mut *(inner as *mut Slice as *mut OsStr) }
527 /// Yields a [`&str`] slice if the `OsStr` is valid Unicode.
529 /// This conversion may entail doing a check for UTF-8 validity.
536 /// use std::ffi::OsStr;
538 /// let os_str = OsStr::new("foo");
539 /// assert_eq!(os_str.to_str(), Some("foo"));
541 #[stable(feature = "rust1", since = "1.0.0")]
542 pub fn to_str(&self) -> Option<&str> {
546 /// Converts an `OsStr` to a [`Cow`]`<`[`str`]`>`.
548 /// Any non-Unicode sequences are replaced with
549 /// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD].
551 /// [U+FFFD]: crate::char::REPLACEMENT_CHARACTER
555 /// Calling `to_string_lossy` on an `OsStr` with invalid unicode:
558 /// // Note, due to differences in how Unix and Windows represent strings,
559 /// // we are forced to complicate this example, setting up example `OsStr`s
560 /// // with different source data and via different platform extensions.
561 /// // Understand that in reality you could end up with such example invalid
562 /// // sequences simply through collecting user command line arguments, for
565 /// #[cfg(any(unix, target_os = "redox"))] {
566 /// use std::ffi::OsStr;
567 /// use std::os::unix::ffi::OsStrExt;
569 /// // Here, the values 0x66 and 0x6f correspond to 'f' and 'o'
570 /// // respectively. The value 0x80 is a lone continuation byte, invalid
571 /// // in a UTF-8 sequence.
572 /// let source = [0x66, 0x6f, 0x80, 0x6f];
573 /// let os_str = OsStr::from_bytes(&source[..]);
575 /// assert_eq!(os_str.to_string_lossy(), "fo�o");
577 /// #[cfg(windows)] {
578 /// use std::ffi::OsString;
579 /// use std::os::windows::prelude::*;
581 /// // Here the values 0x0066 and 0x006f correspond to 'f' and 'o'
582 /// // respectively. The value 0xD800 is a lone surrogate half, invalid
583 /// // in a UTF-16 sequence.
584 /// let source = [0x0066, 0x006f, 0xD800, 0x006f];
585 /// let os_string = OsString::from_wide(&source[..]);
586 /// let os_str = os_string.as_os_str();
588 /// assert_eq!(os_str.to_string_lossy(), "fo�o");
591 #[stable(feature = "rust1", since = "1.0.0")]
592 pub fn to_string_lossy(&self) -> Cow<'_, str> {
593 self.inner.to_string_lossy()
596 /// Copies the slice into an owned [`OsString`].
601 /// use std::ffi::{OsStr, OsString};
603 /// let os_str = OsStr::new("foo");
604 /// let os_string = os_str.to_os_string();
605 /// assert_eq!(os_string, OsString::from("foo"));
607 #[stable(feature = "rust1", since = "1.0.0")]
608 pub fn to_os_string(&self) -> OsString {
609 OsString { inner: self.inner.to_owned() }
612 /// Checks whether the `OsStr` is empty.
617 /// use std::ffi::OsStr;
619 /// let os_str = OsStr::new("");
620 /// assert!(os_str.is_empty());
622 /// let os_str = OsStr::new("foo");
623 /// assert!(!os_str.is_empty());
625 #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
627 pub fn is_empty(&self) -> bool {
628 self.inner.inner.is_empty()
631 /// Returns the length of this `OsStr`.
633 /// Note that this does **not** return the number of bytes in the string in
636 /// The length returned is that of the underlying storage used by `OsStr`.
637 /// As discussed in the [`OsString`] introduction, [`OsString`] and `OsStr`
638 /// store strings in a form best suited for cheap inter-conversion between
639 /// native-platform and Rust string forms, which may differ significantly
640 /// from both of them, including in storage size and encoding.
642 /// This number is simply useful for passing to other methods, like
643 /// [`OsString::with_capacity`] to avoid reallocations.
648 /// use std::ffi::OsStr;
650 /// let os_str = OsStr::new("");
651 /// assert_eq!(os_str.len(), 0);
653 /// let os_str = OsStr::new("foo");
654 /// assert_eq!(os_str.len(), 3);
656 #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
657 pub fn len(&self) -> usize {
658 self.inner.inner.len()
661 /// Converts a [`Box`]`<OsStr>` into an [`OsString`] without copying or allocating.
662 #[stable(feature = "into_boxed_os_str", since = "1.20.0")]
663 pub fn into_os_string(self: Box<OsStr>) -> OsString {
664 let boxed = unsafe { Box::from_raw(Box::into_raw(self) as *mut Slice) };
665 OsString { inner: Buf::from_box(boxed) }
668 /// Gets the underlying byte representation.
670 /// Note: it is *crucial* that this API is private, to avoid
671 /// revealing the internal, platform-specific encodings.
673 fn bytes(&self) -> &[u8] {
674 unsafe { &*(&self.inner as *const _ as *const [u8]) }
677 /// Converts this string to its ASCII lower case equivalent in-place.
679 /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
680 /// but non-ASCII letters are unchanged.
682 /// To return a new lowercased value without modifying the existing one, use
683 /// [`OsStr::to_ascii_lowercase`].
688 /// #![feature(osstring_ascii)]
689 /// use std::ffi::OsString;
691 /// let mut s = OsString::from("GRÜßE, JÜRGEN ❤");
693 /// s.make_ascii_lowercase();
695 /// assert_eq!("grÜße, jÜrgen ❤", s);
697 #[unstable(feature = "osstring_ascii", issue = "70516")]
698 pub fn make_ascii_lowercase(&mut self) {
699 self.inner.make_ascii_lowercase()
702 /// Converts this string to its ASCII upper case equivalent in-place.
704 /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
705 /// but non-ASCII letters are unchanged.
707 /// To return a new uppercased value without modifying the existing one, use
708 /// [`OsStr::to_ascii_uppercase`].
713 /// #![feature(osstring_ascii)]
714 /// use std::ffi::OsString;
716 /// let mut s = OsString::from("Grüße, Jürgen ❤");
718 /// s.make_ascii_uppercase();
720 /// assert_eq!("GRüßE, JüRGEN ❤", s);
722 #[unstable(feature = "osstring_ascii", issue = "70516")]
723 pub fn make_ascii_uppercase(&mut self) {
724 self.inner.make_ascii_uppercase()
727 /// Returns a copy of this string where each character is mapped to its
728 /// ASCII lower case equivalent.
730 /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
731 /// but non-ASCII letters are unchanged.
733 /// To lowercase the value in-place, use [`OsStr::make_ascii_lowercase`].
738 /// #![feature(osstring_ascii)]
739 /// use std::ffi::OsString;
740 /// let s = OsString::from("Grüße, Jürgen ❤");
742 /// assert_eq!("grüße, jürgen ❤", s.to_ascii_lowercase());
744 #[unstable(feature = "osstring_ascii", issue = "70516")]
745 pub fn to_ascii_lowercase(&self) -> OsString {
746 OsString::from_inner(self.inner.to_ascii_lowercase())
749 /// Returns a copy of this string where each character is mapped to its
750 /// ASCII upper case equivalent.
752 /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
753 /// but non-ASCII letters are unchanged.
755 /// To uppercase the value in-place, use [`OsStr::make_ascii_uppercase`].
760 /// #![feature(osstring_ascii)]
761 /// use std::ffi::OsString;
762 /// let s = OsString::from("Grüße, Jürgen ❤");
764 /// assert_eq!("GRüßE, JüRGEN ❤", s.to_ascii_uppercase());
766 #[unstable(feature = "osstring_ascii", issue = "70516")]
767 pub fn to_ascii_uppercase(&self) -> OsString {
768 OsString::from_inner(self.inner.to_ascii_uppercase())
771 /// Checks if all characters in this string are within the ASCII range.
776 /// #![feature(osstring_ascii)]
777 /// use std::ffi::OsString;
779 /// let ascii = OsString::from("hello!\n");
780 /// let non_ascii = OsString::from("Grüße, Jürgen ❤");
782 /// assert!(ascii.is_ascii());
783 /// assert!(!non_ascii.is_ascii());
785 #[unstable(feature = "osstring_ascii", issue = "70516")]
786 pub fn is_ascii(&self) -> bool {
787 self.inner.is_ascii()
790 /// Checks that two strings are an ASCII case-insensitive match.
792 /// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`,
793 /// but without allocating and copying temporaries.
798 /// #![feature(osstring_ascii)]
799 /// use std::ffi::OsString;
801 /// assert!(OsString::from("Ferris").eq_ignore_ascii_case("FERRIS"));
802 /// assert!(OsString::from("Ferrös").eq_ignore_ascii_case("FERRöS"));
803 /// assert!(!OsString::from("Ferrös").eq_ignore_ascii_case("FERRÖS"));
805 #[unstable(feature = "osstring_ascii", issue = "70516")]
806 pub fn eq_ignore_ascii_case<S: ?Sized + AsRef<OsStr>>(&self, other: &S) -> bool {
807 self.inner.eq_ignore_ascii_case(&other.as_ref().inner)
811 #[stable(feature = "box_from_os_str", since = "1.17.0")]
812 impl From<&OsStr> for Box<OsStr> {
813 fn from(s: &OsStr) -> Box<OsStr> {
814 let rw = Box::into_raw(s.inner.into_box()) as *mut OsStr;
815 unsafe { Box::from_raw(rw) }
819 #[stable(feature = "box_from_cow", since = "1.45.0")]
820 impl From<Cow<'_, OsStr>> for Box<OsStr> {
822 fn from(cow: Cow<'_, OsStr>) -> Box<OsStr> {
824 Cow::Borrowed(s) => Box::from(s),
825 Cow::Owned(s) => Box::from(s),
830 #[stable(feature = "os_string_from_box", since = "1.18.0")]
831 impl From<Box<OsStr>> for OsString {
832 /// Converts a [`Box`]`<`[`OsStr`]`>` into a `OsString` without copying or
834 fn from(boxed: Box<OsStr>) -> OsString {
835 boxed.into_os_string()
839 #[stable(feature = "box_from_os_string", since = "1.20.0")]
840 impl From<OsString> for Box<OsStr> {
841 /// Converts a [`OsString`] into a [`Box`]`<OsStr>` without copying or allocating.
842 fn from(s: OsString) -> Box<OsStr> {
843 s.into_boxed_os_str()
847 #[stable(feature = "more_box_slice_clone", since = "1.29.0")]
848 impl Clone for Box<OsStr> {
850 fn clone(&self) -> Self {
851 self.to_os_string().into_boxed_os_str()
855 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
856 impl From<OsString> for Arc<OsStr> {
857 /// Converts a [`OsString`] into a [`Arc`]`<OsStr>` without copying or allocating.
859 fn from(s: OsString) -> Arc<OsStr> {
860 let arc = s.inner.into_arc();
861 unsafe { Arc::from_raw(Arc::into_raw(arc) as *const OsStr) }
865 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
866 impl From<&OsStr> for Arc<OsStr> {
868 fn from(s: &OsStr) -> Arc<OsStr> {
869 let arc = s.inner.into_arc();
870 unsafe { Arc::from_raw(Arc::into_raw(arc) as *const OsStr) }
874 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
875 impl From<OsString> for Rc<OsStr> {
876 /// Converts a [`OsString`] into a [`Rc`]`<OsStr>` without copying or allocating.
878 fn from(s: OsString) -> Rc<OsStr> {
879 let rc = s.inner.into_rc();
880 unsafe { Rc::from_raw(Rc::into_raw(rc) as *const OsStr) }
884 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
885 impl From<&OsStr> for Rc<OsStr> {
887 fn from(s: &OsStr) -> Rc<OsStr> {
888 let rc = s.inner.into_rc();
889 unsafe { Rc::from_raw(Rc::into_raw(rc) as *const OsStr) }
893 #[stable(feature = "cow_from_osstr", since = "1.28.0")]
894 impl<'a> From<OsString> for Cow<'a, OsStr> {
896 fn from(s: OsString) -> Cow<'a, OsStr> {
901 #[stable(feature = "cow_from_osstr", since = "1.28.0")]
902 impl<'a> From<&'a OsStr> for Cow<'a, OsStr> {
904 fn from(s: &'a OsStr) -> Cow<'a, OsStr> {
909 #[stable(feature = "cow_from_osstr", since = "1.28.0")]
910 impl<'a> From<&'a OsString> for Cow<'a, OsStr> {
912 fn from(s: &'a OsString) -> Cow<'a, OsStr> {
913 Cow::Borrowed(s.as_os_str())
917 #[stable(feature = "osstring_from_cow_osstr", since = "1.28.0")]
918 impl<'a> From<Cow<'a, OsStr>> for OsString {
920 fn from(s: Cow<'a, OsStr>) -> Self {
925 #[stable(feature = "box_default_extra", since = "1.17.0")]
926 impl Default for Box<OsStr> {
927 fn default() -> Box<OsStr> {
928 let rw = Box::into_raw(Slice::empty_box()) as *mut OsStr;
929 unsafe { Box::from_raw(rw) }
933 #[stable(feature = "osstring_default", since = "1.9.0")]
934 impl Default for &OsStr {
935 /// Creates an empty `OsStr`.
937 fn default() -> Self {
942 #[stable(feature = "rust1", since = "1.0.0")]
943 impl PartialEq for OsStr {
945 fn eq(&self, other: &OsStr) -> bool {
946 self.bytes().eq(other.bytes())
950 #[stable(feature = "rust1", since = "1.0.0")]
951 impl PartialEq<str> for OsStr {
953 fn eq(&self, other: &str) -> bool {
954 *self == *OsStr::new(other)
958 #[stable(feature = "rust1", since = "1.0.0")]
959 impl PartialEq<OsStr> for str {
961 fn eq(&self, other: &OsStr) -> bool {
962 *other == *OsStr::new(self)
966 #[stable(feature = "rust1", since = "1.0.0")]
969 #[stable(feature = "rust1", since = "1.0.0")]
970 impl PartialOrd for OsStr {
972 fn partial_cmp(&self, other: &OsStr) -> Option<cmp::Ordering> {
973 self.bytes().partial_cmp(other.bytes())
976 fn lt(&self, other: &OsStr) -> bool {
977 self.bytes().lt(other.bytes())
980 fn le(&self, other: &OsStr) -> bool {
981 self.bytes().le(other.bytes())
984 fn gt(&self, other: &OsStr) -> bool {
985 self.bytes().gt(other.bytes())
988 fn ge(&self, other: &OsStr) -> bool {
989 self.bytes().ge(other.bytes())
993 #[stable(feature = "rust1", since = "1.0.0")]
994 impl PartialOrd<str> for OsStr {
996 fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
997 self.partial_cmp(OsStr::new(other))
1001 // FIXME (#19470): cannot provide PartialOrd<OsStr> for str until we
1002 // have more flexible coherence rules.
1004 #[stable(feature = "rust1", since = "1.0.0")]
1005 impl Ord for OsStr {
1007 fn cmp(&self, other: &OsStr) -> cmp::Ordering {
1008 self.bytes().cmp(other.bytes())
1012 macro_rules! impl_cmp {
1013 ($lhs:ty, $rhs: ty) => {
1014 #[stable(feature = "cmp_os_str", since = "1.8.0")]
1015 impl<'a, 'b> PartialEq<$rhs> for $lhs {
1017 fn eq(&self, other: &$rhs) -> bool {
1018 <OsStr as PartialEq>::eq(self, other)
1022 #[stable(feature = "cmp_os_str", since = "1.8.0")]
1023 impl<'a, 'b> PartialEq<$lhs> for $rhs {
1025 fn eq(&self, other: &$lhs) -> bool {
1026 <OsStr as PartialEq>::eq(self, other)
1030 #[stable(feature = "cmp_os_str", since = "1.8.0")]
1031 impl<'a, 'b> PartialOrd<$rhs> for $lhs {
1033 fn partial_cmp(&self, other: &$rhs) -> Option<cmp::Ordering> {
1034 <OsStr as PartialOrd>::partial_cmp(self, other)
1038 #[stable(feature = "cmp_os_str", since = "1.8.0")]
1039 impl<'a, 'b> PartialOrd<$lhs> for $rhs {
1041 fn partial_cmp(&self, other: &$lhs) -> Option<cmp::Ordering> {
1042 <OsStr as PartialOrd>::partial_cmp(self, other)
1048 impl_cmp!(OsString, OsStr);
1049 impl_cmp!(OsString, &'a OsStr);
1050 impl_cmp!(Cow<'a, OsStr>, OsStr);
1051 impl_cmp!(Cow<'a, OsStr>, &'b OsStr);
1052 impl_cmp!(Cow<'a, OsStr>, OsString);
1054 #[stable(feature = "rust1", since = "1.0.0")]
1055 impl Hash for OsStr {
1057 fn hash<H: Hasher>(&self, state: &mut H) {
1058 self.bytes().hash(state)
1062 #[stable(feature = "rust1", since = "1.0.0")]
1063 impl fmt::Debug for OsStr {
1064 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1065 fmt::Debug::fmt(&self.inner, formatter)
1070 pub(crate) fn display(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1071 fmt::Display::fmt(&self.inner, formatter)
1075 #[stable(feature = "rust1", since = "1.0.0")]
1076 impl Borrow<OsStr> for OsString {
1077 fn borrow(&self) -> &OsStr {
1082 #[stable(feature = "rust1", since = "1.0.0")]
1083 impl ToOwned for OsStr {
1084 type Owned = OsString;
1085 fn to_owned(&self) -> OsString {
1088 fn clone_into(&self, target: &mut OsString) {
1089 self.inner.clone_into(&mut target.inner)
1093 #[stable(feature = "rust1", since = "1.0.0")]
1094 impl AsRef<OsStr> for OsStr {
1095 fn as_ref(&self) -> &OsStr {
1100 #[stable(feature = "rust1", since = "1.0.0")]
1101 impl AsRef<OsStr> for OsString {
1103 fn as_ref(&self) -> &OsStr {
1108 #[stable(feature = "rust1", since = "1.0.0")]
1109 impl AsRef<OsStr> for str {
1111 fn as_ref(&self) -> &OsStr {
1112 OsStr::from_inner(Slice::from_str(self))
1116 #[stable(feature = "rust1", since = "1.0.0")]
1117 impl AsRef<OsStr> for String {
1119 fn as_ref(&self) -> &OsStr {
1124 impl FromInner<Buf> for OsString {
1125 fn from_inner(buf: Buf) -> OsString {
1126 OsString { inner: buf }
1130 impl IntoInner<Buf> for OsString {
1131 fn into_inner(self) -> Buf {
1136 impl AsInner<Slice> for OsStr {
1138 fn as_inner(&self) -> &Slice {
1143 #[stable(feature = "osstring_from_str", since = "1.45.0")]
1144 impl FromStr for OsString {
1145 type Err = core::convert::Infallible;
1147 fn from_str(s: &str) -> Result<Self, Self::Err> {
1148 Ok(OsString::from(s))