std/ffi/
os_str.rs

1//! The [`OsStr`] and [`OsString`] types and associated utilities.
2
3#[cfg(test)]
4mod tests;
5
6use core::clone::CloneToUninit;
7
8use crate::borrow::{Borrow, Cow};
9use crate::collections::TryReserveError;
10use crate::hash::{Hash, Hasher};
11use crate::ops::{self, Range};
12use crate::rc::Rc;
13use crate::str::FromStr;
14use crate::sync::Arc;
15use crate::sys::os_str::{Buf, Slice};
16use crate::sys_common::{AsInner, FromInner, IntoInner};
17use crate::{cmp, fmt, slice};
18
19/// A type that can represent owned, mutable platform-native strings, but is
20/// cheaply inter-convertible with Rust strings.
21///
22/// The need for this type arises from the fact that:
23///
24/// * On Unix systems, strings are often arbitrary sequences of non-zero
25///   bytes, in many cases interpreted as UTF-8.
26///
27/// * On Windows, strings are often arbitrary sequences of non-zero 16-bit
28///   values, interpreted as UTF-16 when it is valid to do so.
29///
30/// * In Rust, strings are always valid UTF-8, which may contain zeros.
31///
32/// `OsString` and [`OsStr`] bridge this gap by simultaneously representing Rust
33/// and platform-native string values, and in particular allowing a Rust string
34/// to be converted into an "OS" string with no cost if possible. A consequence
35/// of this is that `OsString` instances are *not* `NUL` terminated; in order
36/// to pass to e.g., Unix system call, you should create a [`CStr`].
37///
38/// `OsString` is to <code>&[OsStr]</code> as [`String`] is to <code>&[str]</code>: the former
39/// in each pair are owned strings; the latter are borrowed
40/// references.
41///
42/// Note, `OsString` and [`OsStr`] internally do not necessarily hold strings in
43/// the form native to the platform; While on Unix, strings are stored as a
44/// sequence of 8-bit values, on Windows, where strings are 16-bit value based
45/// as just discussed, strings are also actually stored as a sequence of 8-bit
46/// values, encoded in a less-strict variant of UTF-8. This is useful to
47/// understand when handling capacity and length values.
48///
49/// # Capacity of `OsString`
50///
51/// Capacity uses units of UTF-8 bytes for OS strings which were created from valid unicode, and
52/// uses units of bytes in an unspecified encoding for other contents. On a given target, all
53/// `OsString` and `OsStr` values use the same units for capacity, so the following will work:
54/// ```
55/// use std::ffi::{OsStr, OsString};
56///
57/// fn concat_os_strings(a: &OsStr, b: &OsStr) -> OsString {
58///     let mut ret = OsString::with_capacity(a.len() + b.len()); // This will allocate
59///     ret.push(a); // This will not allocate further
60///     ret.push(b); // This will not allocate further
61///     ret
62/// }
63/// ```
64///
65/// # Creating an `OsString`
66///
67/// **From a Rust string**: `OsString` implements
68/// <code>[From]<[String]></code>, so you can use <code>my_string.[into]\()</code> to
69/// create an `OsString` from a normal Rust string.
70///
71/// **From slices:** Just like you can start with an empty Rust
72/// [`String`] and then [`String::push_str`] some <code>&[str]</code>
73/// sub-string slices into it, you can create an empty `OsString` with
74/// the [`OsString::new`] method and then push string slices into it with the
75/// [`OsString::push`] method.
76///
77/// # Extracting a borrowed reference to the whole OS string
78///
79/// You can use the [`OsString::as_os_str`] method to get an <code>&[OsStr]</code> from
80/// an `OsString`; this is effectively a borrowed reference to the
81/// whole string.
82///
83/// # Conversions
84///
85/// See the [module's toplevel documentation about conversions][conversions] for a discussion on
86/// the traits which `OsString` implements for [conversions] from/to native representations.
87///
88/// [`CStr`]: crate::ffi::CStr
89/// [conversions]: super#conversions
90/// [into]: Into::into
91#[cfg_attr(not(test), rustc_diagnostic_item = "OsString")]
92#[stable(feature = "rust1", since = "1.0.0")]
93pub struct OsString {
94    inner: Buf,
95}
96
97/// Allows extension traits within `std`.
98#[unstable(feature = "sealed", issue = "none")]
99impl crate::sealed::Sealed for OsString {}
100
101/// Borrowed reference to an OS string (see [`OsString`]).
102///
103/// This type represents a borrowed reference to a string in the operating system's preferred
104/// representation.
105///
106/// `&OsStr` is to [`OsString`] as <code>&[str]</code> is to [`String`]: the
107/// former in each pair are borrowed references; the latter are owned strings.
108///
109/// See the [module's toplevel documentation about conversions][conversions] for a discussion on
110/// the traits which `OsStr` implements for [conversions] from/to native representations.
111///
112/// [conversions]: super#conversions
113#[cfg_attr(not(test), rustc_diagnostic_item = "OsStr")]
114#[stable(feature = "rust1", since = "1.0.0")]
115// `OsStr::from_inner` and `impl CloneToUninit for OsStr` current implementation relies
116// on `OsStr` being layout-compatible with `Slice`.
117// However, `OsStr` layout is considered an implementation detail and must not be relied upon.
118#[repr(transparent)]
119pub struct OsStr {
120    inner: Slice,
121}
122
123/// Allows extension traits within `std`.
124#[unstable(feature = "sealed", issue = "none")]
125impl crate::sealed::Sealed for OsStr {}
126
127impl OsString {
128    /// Constructs a new empty `OsString`.
129    ///
130    /// # Examples
131    ///
132    /// ```
133    /// use std::ffi::OsString;
134    ///
135    /// let os_string = OsString::new();
136    /// ```
137    #[stable(feature = "rust1", since = "1.0.0")]
138    #[must_use]
139    #[inline]
140    pub fn new() -> OsString {
141        OsString { inner: Buf::from_string(String::new()) }
142    }
143
144    /// Converts bytes to an `OsString` without checking that the bytes contains
145    /// valid [`OsStr`]-encoded data.
146    ///
147    /// The byte encoding is an unspecified, platform-specific, self-synchronizing superset of UTF-8.
148    /// By being a self-synchronizing superset of UTF-8, this encoding is also a superset of 7-bit
149    /// ASCII.
150    ///
151    /// See the [module's toplevel documentation about conversions][conversions] for safe,
152    /// cross-platform [conversions] from/to native representations.
153    ///
154    /// # Safety
155    ///
156    /// As the encoding is unspecified, callers must pass in bytes that originated as a mixture of
157    /// validated UTF-8 and bytes from [`OsStr::as_encoded_bytes`] from within the same Rust version
158    /// built for the same target platform.  For example, reconstructing an `OsString` from bytes sent
159    /// over the network or stored in a file will likely violate these safety rules.
160    ///
161    /// Due to the encoding being self-synchronizing, the bytes from [`OsStr::as_encoded_bytes`] can be
162    /// split either immediately before or immediately after any valid non-empty UTF-8 substring.
163    ///
164    /// # Example
165    ///
166    /// ```
167    /// use std::ffi::OsStr;
168    ///
169    /// let os_str = OsStr::new("Mary had a little lamb");
170    /// let bytes = os_str.as_encoded_bytes();
171    /// let words = bytes.split(|b| *b == b' ');
172    /// let words: Vec<&OsStr> = words.map(|word| {
173    ///     // SAFETY:
174    ///     // - Each `word` only contains content that originated from `OsStr::as_encoded_bytes`
175    ///     // - Only split with ASCII whitespace which is a non-empty UTF-8 substring
176    ///     unsafe { OsStr::from_encoded_bytes_unchecked(word) }
177    /// }).collect();
178    /// ```
179    ///
180    /// [conversions]: super#conversions
181    #[inline]
182    #[stable(feature = "os_str_bytes", since = "1.74.0")]
183    pub unsafe fn from_encoded_bytes_unchecked(bytes: Vec<u8>) -> Self {
184        OsString { inner: unsafe { Buf::from_encoded_bytes_unchecked(bytes) } }
185    }
186
187    /// Converts to an [`OsStr`] slice.
188    ///
189    /// # Examples
190    ///
191    /// ```
192    /// use std::ffi::{OsString, OsStr};
193    ///
194    /// let os_string = OsString::from("foo");
195    /// let os_str = OsStr::new("foo");
196    /// assert_eq!(os_string.as_os_str(), os_str);
197    /// ```
198    #[cfg_attr(not(test), rustc_diagnostic_item = "os_string_as_os_str")]
199    #[stable(feature = "rust1", since = "1.0.0")]
200    #[must_use]
201    #[inline]
202    pub fn as_os_str(&self) -> &OsStr {
203        self
204    }
205
206    /// Converts the `OsString` into a byte vector.  To convert the byte vector back into an
207    /// `OsString`, use the [`OsString::from_encoded_bytes_unchecked`] function.
208    ///
209    /// The byte encoding is an unspecified, platform-specific, self-synchronizing superset of UTF-8.
210    /// By being a self-synchronizing superset of UTF-8, this encoding is also a superset of 7-bit
211    /// ASCII.
212    ///
213    /// Note: As the encoding is unspecified, any sub-slice of bytes that is not valid UTF-8 should
214    /// be treated as opaque and only comparable within the same Rust version built for the same
215    /// target platform.  For example, sending the bytes over the network or storing it in a file
216    /// will likely result in incompatible data.  See [`OsString`] for more encoding details
217    /// and [`std::ffi`] for platform-specific, specified conversions.
218    ///
219    /// [`std::ffi`]: crate::ffi
220    #[inline]
221    #[stable(feature = "os_str_bytes", since = "1.74.0")]
222    pub fn into_encoded_bytes(self) -> Vec<u8> {
223        self.inner.into_encoded_bytes()
224    }
225
226    /// Converts the `OsString` into a [`String`] if it contains valid Unicode data.
227    ///
228    /// On failure, ownership of the original `OsString` is returned.
229    ///
230    /// # Examples
231    ///
232    /// ```
233    /// use std::ffi::OsString;
234    ///
235    /// let os_string = OsString::from("foo");
236    /// let string = os_string.into_string();
237    /// assert_eq!(string, Ok(String::from("foo")));
238    /// ```
239    #[stable(feature = "rust1", since = "1.0.0")]
240    #[inline]
241    pub fn into_string(self) -> Result<String, OsString> {
242        self.inner.into_string().map_err(|buf| OsString { inner: buf })
243    }
244
245    /// Extends the string with the given <code>&[OsStr]</code> slice.
246    ///
247    /// # Examples
248    ///
249    /// ```
250    /// use std::ffi::OsString;
251    ///
252    /// let mut os_string = OsString::from("foo");
253    /// os_string.push("bar");
254    /// assert_eq!(&os_string, "foobar");
255    /// ```
256    #[stable(feature = "rust1", since = "1.0.0")]
257    #[inline]
258    #[rustc_confusables("append", "put")]
259    pub fn push<T: AsRef<OsStr>>(&mut self, s: T) {
260        trait SpecPushTo {
261            fn spec_push_to(&self, buf: &mut OsString);
262        }
263
264        impl<T: AsRef<OsStr>> SpecPushTo for T {
265            #[inline]
266            default fn spec_push_to(&self, buf: &mut OsString) {
267                buf.inner.push_slice(&self.as_ref().inner);
268            }
269        }
270
271        // Use a more efficient implementation when the string is UTF-8.
272        macro spec_str($T:ty) {
273            impl SpecPushTo for $T {
274                #[inline]
275                fn spec_push_to(&self, buf: &mut OsString) {
276                    buf.inner.push_str(self);
277                }
278            }
279        }
280        spec_str!(str);
281        spec_str!(String);
282
283        s.spec_push_to(self)
284    }
285
286    /// Creates a new `OsString` with at least the given capacity.
287    ///
288    /// The string will be able to hold at least `capacity` length units of other
289    /// OS strings without reallocating. This method is allowed to allocate for
290    /// more units than `capacity`. If `capacity` is 0, the string will not
291    /// allocate.
292    ///
293    /// See the main `OsString` documentation information about encoding and capacity units.
294    ///
295    /// # Examples
296    ///
297    /// ```
298    /// use std::ffi::OsString;
299    ///
300    /// let mut os_string = OsString::with_capacity(10);
301    /// let capacity = os_string.capacity();
302    ///
303    /// // This push is done without reallocating
304    /// os_string.push("foo");
305    ///
306    /// assert_eq!(capacity, os_string.capacity());
307    /// ```
308    #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
309    #[must_use]
310    #[inline]
311    pub fn with_capacity(capacity: usize) -> OsString {
312        OsString { inner: Buf::with_capacity(capacity) }
313    }
314
315    /// Truncates the `OsString` to zero length.
316    ///
317    /// # Examples
318    ///
319    /// ```
320    /// use std::ffi::OsString;
321    ///
322    /// let mut os_string = OsString::from("foo");
323    /// assert_eq!(&os_string, "foo");
324    ///
325    /// os_string.clear();
326    /// assert_eq!(&os_string, "");
327    /// ```
328    #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
329    #[inline]
330    pub fn clear(&mut self) {
331        self.inner.clear()
332    }
333
334    /// Returns the capacity this `OsString` can hold without reallocating.
335    ///
336    /// See the main `OsString` documentation information about encoding and capacity units.
337    ///
338    /// # Examples
339    ///
340    /// ```
341    /// use std::ffi::OsString;
342    ///
343    /// let os_string = OsString::with_capacity(10);
344    /// assert!(os_string.capacity() >= 10);
345    /// ```
346    #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
347    #[must_use]
348    #[inline]
349    pub fn capacity(&self) -> usize {
350        self.inner.capacity()
351    }
352
353    /// Reserves capacity for at least `additional` more capacity to be inserted
354    /// in the given `OsString`. Does nothing if the capacity is
355    /// already sufficient.
356    ///
357    /// The collection may reserve more space to speculatively avoid frequent reallocations.
358    ///
359    /// See the main `OsString` documentation information about encoding and capacity units.
360    ///
361    /// # Examples
362    ///
363    /// ```
364    /// use std::ffi::OsString;
365    ///
366    /// let mut s = OsString::new();
367    /// s.reserve(10);
368    /// assert!(s.capacity() >= 10);
369    /// ```
370    #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
371    #[inline]
372    pub fn reserve(&mut self, additional: usize) {
373        self.inner.reserve(additional)
374    }
375
376    /// Tries to reserve capacity for at least `additional` more length units
377    /// in the given `OsString`. The string may reserve more space to speculatively avoid
378    /// frequent reallocations. After calling `try_reserve`, capacity will be
379    /// greater than or equal to `self.len() + additional` if it returns `Ok(())`.
380    /// Does nothing if capacity is already sufficient. This method preserves
381    /// the contents even if an error occurs.
382    ///
383    /// See the main `OsString` documentation information about encoding and capacity units.
384    ///
385    /// # Errors
386    ///
387    /// If the capacity overflows, or the allocator reports a failure, then an error
388    /// is returned.
389    ///
390    /// # Examples
391    ///
392    /// ```
393    /// use std::ffi::{OsStr, OsString};
394    /// use std::collections::TryReserveError;
395    ///
396    /// fn process_data(data: &str) -> Result<OsString, TryReserveError> {
397    ///     let mut s = OsString::new();
398    ///
399    ///     // Pre-reserve the memory, exiting if we can't
400    ///     s.try_reserve(OsStr::new(data).len())?;
401    ///
402    ///     // Now we know this can't OOM in the middle of our complex work
403    ///     s.push(data);
404    ///
405    ///     Ok(s)
406    /// }
407    /// # process_data("123").expect("why is the test harness OOMing on 3 bytes?");
408    /// ```
409    #[stable(feature = "try_reserve_2", since = "1.63.0")]
410    #[inline]
411    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
412        self.inner.try_reserve(additional)
413    }
414
415    /// Reserves the minimum capacity for at least `additional` more capacity to
416    /// be inserted in the given `OsString`. Does nothing if the capacity is
417    /// already sufficient.
418    ///
419    /// Note that the allocator may give the collection more space than it
420    /// requests. Therefore, capacity can not be relied upon to be precisely
421    /// minimal. Prefer [`reserve`] if future insertions are expected.
422    ///
423    /// [`reserve`]: OsString::reserve
424    ///
425    /// See the main `OsString` documentation information about encoding and capacity units.
426    ///
427    /// # Examples
428    ///
429    /// ```
430    /// use std::ffi::OsString;
431    ///
432    /// let mut s = OsString::new();
433    /// s.reserve_exact(10);
434    /// assert!(s.capacity() >= 10);
435    /// ```
436    #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
437    #[inline]
438    pub fn reserve_exact(&mut self, additional: usize) {
439        self.inner.reserve_exact(additional)
440    }
441
442    /// Tries to reserve the minimum capacity for at least `additional`
443    /// more length units in the given `OsString`. After calling
444    /// `try_reserve_exact`, capacity will be greater than or equal to
445    /// `self.len() + additional` if it returns `Ok(())`.
446    /// Does nothing if the capacity is already sufficient.
447    ///
448    /// Note that the allocator may give the `OsString` more space than it
449    /// requests. Therefore, capacity can not be relied upon to be precisely
450    /// minimal. Prefer [`try_reserve`] if future insertions are expected.
451    ///
452    /// [`try_reserve`]: OsString::try_reserve
453    ///
454    /// See the main `OsString` documentation information about encoding and capacity units.
455    ///
456    /// # Errors
457    ///
458    /// If the capacity overflows, or the allocator reports a failure, then an error
459    /// is returned.
460    ///
461    /// # Examples
462    ///
463    /// ```
464    /// use std::ffi::{OsStr, OsString};
465    /// use std::collections::TryReserveError;
466    ///
467    /// fn process_data(data: &str) -> Result<OsString, TryReserveError> {
468    ///     let mut s = OsString::new();
469    ///
470    ///     // Pre-reserve the memory, exiting if we can't
471    ///     s.try_reserve_exact(OsStr::new(data).len())?;
472    ///
473    ///     // Now we know this can't OOM in the middle of our complex work
474    ///     s.push(data);
475    ///
476    ///     Ok(s)
477    /// }
478    /// # process_data("123").expect("why is the test harness OOMing on 3 bytes?");
479    /// ```
480    #[stable(feature = "try_reserve_2", since = "1.63.0")]
481    #[inline]
482    pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
483        self.inner.try_reserve_exact(additional)
484    }
485
486    /// Shrinks the capacity of the `OsString` to match its length.
487    ///
488    /// See the main `OsString` documentation information about encoding and capacity units.
489    ///
490    /// # Examples
491    ///
492    /// ```
493    /// use std::ffi::OsString;
494    ///
495    /// let mut s = OsString::from("foo");
496    ///
497    /// s.reserve(100);
498    /// assert!(s.capacity() >= 100);
499    ///
500    /// s.shrink_to_fit();
501    /// assert_eq!(3, s.capacity());
502    /// ```
503    #[stable(feature = "osstring_shrink_to_fit", since = "1.19.0")]
504    #[inline]
505    pub fn shrink_to_fit(&mut self) {
506        self.inner.shrink_to_fit()
507    }
508
509    /// Shrinks the capacity of the `OsString` with a lower bound.
510    ///
511    /// The capacity will remain at least as large as both the length
512    /// and the supplied value.
513    ///
514    /// If the current capacity is less than the lower limit, this is a no-op.
515    ///
516    /// See the main `OsString` documentation information about encoding and capacity units.
517    ///
518    /// # Examples
519    ///
520    /// ```
521    /// use std::ffi::OsString;
522    ///
523    /// let mut s = OsString::from("foo");
524    ///
525    /// s.reserve(100);
526    /// assert!(s.capacity() >= 100);
527    ///
528    /// s.shrink_to(10);
529    /// assert!(s.capacity() >= 10);
530    /// s.shrink_to(0);
531    /// assert!(s.capacity() >= 3);
532    /// ```
533    #[inline]
534    #[stable(feature = "shrink_to", since = "1.56.0")]
535    pub fn shrink_to(&mut self, min_capacity: usize) {
536        self.inner.shrink_to(min_capacity)
537    }
538
539    /// Converts this `OsString` into a boxed [`OsStr`].
540    ///
541    /// # Examples
542    ///
543    /// ```
544    /// use std::ffi::{OsString, OsStr};
545    ///
546    /// let s = OsString::from("hello");
547    ///
548    /// let b: Box<OsStr> = s.into_boxed_os_str();
549    /// ```
550    #[must_use = "`self` will be dropped if the result is not used"]
551    #[stable(feature = "into_boxed_os_str", since = "1.20.0")]
552    pub fn into_boxed_os_str(self) -> Box<OsStr> {
553        let rw = Box::into_raw(self.inner.into_box()) as *mut OsStr;
554        unsafe { Box::from_raw(rw) }
555    }
556
557    /// Consumes and leaks the `OsString`, returning a mutable reference to the contents,
558    /// `&'a mut OsStr`.
559    ///
560    /// The caller has free choice over the returned lifetime, including 'static.
561    /// Indeed, this function is ideally used for data that lives for the remainder of
562    /// the program’s life, as dropping the returned reference will cause a memory leak.
563    ///
564    /// It does not reallocate or shrink the `OsString`, so the leaked allocation may include
565    /// unused capacity that is not part of the returned slice. If you want to discard excess
566    /// capacity, call [`into_boxed_os_str`], and then [`Box::leak`] instead.
567    /// However, keep in mind that trimming the capacity may result in a reallocation and copy.
568    ///
569    /// [`into_boxed_os_str`]: Self::into_boxed_os_str
570    #[unstable(feature = "os_string_pathbuf_leak", issue = "125965")]
571    #[inline]
572    pub fn leak<'a>(self) -> &'a mut OsStr {
573        OsStr::from_inner_mut(self.inner.leak())
574    }
575
576    /// Truncate the `OsString` to the specified length.
577    ///
578    /// # Panics
579    /// Panics if `len` does not lie on a valid `OsStr` boundary
580    /// (as described in [`OsStr::slice_encoded_bytes`]).
581    #[inline]
582    #[unstable(feature = "os_string_truncate", issue = "133262")]
583    pub fn truncate(&mut self, len: usize) {
584        self.as_os_str().inner.check_public_boundary(len);
585        // SAFETY: The length was just checked to be at a valid boundary.
586        unsafe { self.inner.truncate_unchecked(len) };
587    }
588
589    /// Provides plumbing to `Vec::extend_from_slice` without giving full
590    /// mutable access to the `Vec`.
591    ///
592    /// # Safety
593    ///
594    /// The slice must be valid for the platform encoding (as described in
595    /// [`OsStr::from_encoded_bytes_unchecked`]).
596    ///
597    /// This bypasses the encoding-dependent surrogate joining, so `self` must
598    /// not end with a leading surrogate half and `other` must not start with
599    /// with a trailing surrogate half.
600    #[inline]
601    pub(crate) unsafe fn extend_from_slice_unchecked(&mut self, other: &[u8]) {
602        // SAFETY: Guaranteed by caller.
603        unsafe { self.inner.extend_from_slice_unchecked(other) };
604    }
605}
606
607#[stable(feature = "rust1", since = "1.0.0")]
608impl From<String> for OsString {
609    /// Converts a [`String`] into an [`OsString`].
610    ///
611    /// This conversion does not allocate or copy memory.
612    #[inline]
613    fn from(s: String) -> OsString {
614        OsString { inner: Buf::from_string(s) }
615    }
616}
617
618#[stable(feature = "rust1", since = "1.0.0")]
619impl<T: ?Sized + AsRef<OsStr>> From<&T> for OsString {
620    /// Copies any value implementing <code>[AsRef]&lt;[OsStr]&gt;</code>
621    /// into a newly allocated [`OsString`].
622    fn from(s: &T) -> OsString {
623        trait SpecToOsString {
624            fn spec_to_os_string(&self) -> OsString;
625        }
626
627        impl<T: AsRef<OsStr>> SpecToOsString for T {
628            #[inline]
629            default fn spec_to_os_string(&self) -> OsString {
630                self.as_ref().to_os_string()
631            }
632        }
633
634        // Preserve the known-UTF-8 property for strings.
635        macro spec_str($T:ty) {
636            impl SpecToOsString for $T {
637                #[inline]
638                fn spec_to_os_string(&self) -> OsString {
639                    OsString::from(String::from(self))
640                }
641            }
642        }
643        spec_str!(str);
644        spec_str!(String);
645
646        s.spec_to_os_string()
647    }
648}
649
650#[stable(feature = "rust1", since = "1.0.0")]
651impl ops::Index<ops::RangeFull> for OsString {
652    type Output = OsStr;
653
654    #[inline]
655    fn index(&self, _index: ops::RangeFull) -> &OsStr {
656        OsStr::from_inner(self.inner.as_slice())
657    }
658}
659
660#[stable(feature = "mut_osstr", since = "1.44.0")]
661impl ops::IndexMut<ops::RangeFull> for OsString {
662    #[inline]
663    fn index_mut(&mut self, _index: ops::RangeFull) -> &mut OsStr {
664        OsStr::from_inner_mut(self.inner.as_mut_slice())
665    }
666}
667
668#[stable(feature = "rust1", since = "1.0.0")]
669impl ops::Deref for OsString {
670    type Target = OsStr;
671
672    #[inline]
673    fn deref(&self) -> &OsStr {
674        &self[..]
675    }
676}
677
678#[stable(feature = "mut_osstr", since = "1.44.0")]
679impl ops::DerefMut for OsString {
680    #[inline]
681    fn deref_mut(&mut self) -> &mut OsStr {
682        &mut self[..]
683    }
684}
685
686#[stable(feature = "osstring_default", since = "1.9.0")]
687impl Default for OsString {
688    /// Constructs an empty `OsString`.
689    #[inline]
690    fn default() -> OsString {
691        OsString::new()
692    }
693}
694
695#[stable(feature = "rust1", since = "1.0.0")]
696impl Clone for OsString {
697    #[inline]
698    fn clone(&self) -> Self {
699        OsString { inner: self.inner.clone() }
700    }
701
702    /// Clones the contents of `source` into `self`.
703    ///
704    /// This method is preferred over simply assigning `source.clone()` to `self`,
705    /// as it avoids reallocation if possible.
706    #[inline]
707    fn clone_from(&mut self, source: &Self) {
708        self.inner.clone_from(&source.inner)
709    }
710}
711
712#[stable(feature = "rust1", since = "1.0.0")]
713impl fmt::Debug for OsString {
714    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
715        fmt::Debug::fmt(&**self, formatter)
716    }
717}
718
719#[stable(feature = "rust1", since = "1.0.0")]
720impl PartialEq for OsString {
721    #[inline]
722    fn eq(&self, other: &OsString) -> bool {
723        &**self == &**other
724    }
725}
726
727#[stable(feature = "rust1", since = "1.0.0")]
728impl PartialEq<str> for OsString {
729    #[inline]
730    fn eq(&self, other: &str) -> bool {
731        &**self == other
732    }
733}
734
735#[stable(feature = "rust1", since = "1.0.0")]
736impl PartialEq<OsString> for str {
737    #[inline]
738    fn eq(&self, other: &OsString) -> bool {
739        &**other == self
740    }
741}
742
743#[stable(feature = "os_str_str_ref_eq", since = "1.29.0")]
744impl PartialEq<&str> for OsString {
745    #[inline]
746    fn eq(&self, other: &&str) -> bool {
747        **self == **other
748    }
749}
750
751#[stable(feature = "os_str_str_ref_eq", since = "1.29.0")]
752impl<'a> PartialEq<OsString> for &'a str {
753    #[inline]
754    fn eq(&self, other: &OsString) -> bool {
755        **other == **self
756    }
757}
758
759#[stable(feature = "rust1", since = "1.0.0")]
760impl Eq for OsString {}
761
762#[stable(feature = "rust1", since = "1.0.0")]
763impl PartialOrd for OsString {
764    #[inline]
765    fn partial_cmp(&self, other: &OsString) -> Option<cmp::Ordering> {
766        (&**self).partial_cmp(&**other)
767    }
768    #[inline]
769    fn lt(&self, other: &OsString) -> bool {
770        &**self < &**other
771    }
772    #[inline]
773    fn le(&self, other: &OsString) -> bool {
774        &**self <= &**other
775    }
776    #[inline]
777    fn gt(&self, other: &OsString) -> bool {
778        &**self > &**other
779    }
780    #[inline]
781    fn ge(&self, other: &OsString) -> bool {
782        &**self >= &**other
783    }
784}
785
786#[stable(feature = "rust1", since = "1.0.0")]
787impl PartialOrd<str> for OsString {
788    #[inline]
789    fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
790        (&**self).partial_cmp(other)
791    }
792}
793
794#[stable(feature = "rust1", since = "1.0.0")]
795impl Ord for OsString {
796    #[inline]
797    fn cmp(&self, other: &OsString) -> cmp::Ordering {
798        (&**self).cmp(&**other)
799    }
800}
801
802#[stable(feature = "rust1", since = "1.0.0")]
803impl Hash for OsString {
804    #[inline]
805    fn hash<H: Hasher>(&self, state: &mut H) {
806        (&**self).hash(state)
807    }
808}
809
810#[stable(feature = "os_string_fmt_write", since = "1.64.0")]
811impl fmt::Write for OsString {
812    fn write_str(&mut self, s: &str) -> fmt::Result {
813        self.push(s);
814        Ok(())
815    }
816}
817
818impl OsStr {
819    /// Coerces into an `OsStr` slice.
820    ///
821    /// # Examples
822    ///
823    /// ```
824    /// use std::ffi::OsStr;
825    ///
826    /// let os_str = OsStr::new("foo");
827    /// ```
828    #[inline]
829    #[stable(feature = "rust1", since = "1.0.0")]
830    pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &OsStr {
831        s.as_ref()
832    }
833
834    /// Converts a slice of bytes to an OS string slice without checking that the string contains
835    /// valid `OsStr`-encoded data.
836    ///
837    /// The byte encoding is an unspecified, platform-specific, self-synchronizing superset of UTF-8.
838    /// By being a self-synchronizing superset of UTF-8, this encoding is also a superset of 7-bit
839    /// ASCII.
840    ///
841    /// See the [module's toplevel documentation about conversions][conversions] for safe,
842    /// cross-platform [conversions] from/to native representations.
843    ///
844    /// # Safety
845    ///
846    /// As the encoding is unspecified, callers must pass in bytes that originated as a mixture of
847    /// validated UTF-8 and bytes from [`OsStr::as_encoded_bytes`] from within the same Rust version
848    /// built for the same target platform.  For example, reconstructing an `OsStr` from bytes sent
849    /// over the network or stored in a file will likely violate these safety rules.
850    ///
851    /// Due to the encoding being self-synchronizing, the bytes from [`OsStr::as_encoded_bytes`] can be
852    /// split either immediately before or immediately after any valid non-empty UTF-8 substring.
853    ///
854    /// # Example
855    ///
856    /// ```
857    /// use std::ffi::OsStr;
858    ///
859    /// let os_str = OsStr::new("Mary had a little lamb");
860    /// let bytes = os_str.as_encoded_bytes();
861    /// let words = bytes.split(|b| *b == b' ');
862    /// let words: Vec<&OsStr> = words.map(|word| {
863    ///     // SAFETY:
864    ///     // - Each `word` only contains content that originated from `OsStr::as_encoded_bytes`
865    ///     // - Only split with ASCII whitespace which is a non-empty UTF-8 substring
866    ///     unsafe { OsStr::from_encoded_bytes_unchecked(word) }
867    /// }).collect();
868    /// ```
869    ///
870    /// [conversions]: super#conversions
871    #[inline]
872    #[stable(feature = "os_str_bytes", since = "1.74.0")]
873    pub unsafe fn from_encoded_bytes_unchecked(bytes: &[u8]) -> &Self {
874        Self::from_inner(unsafe { Slice::from_encoded_bytes_unchecked(bytes) })
875    }
876
877    #[inline]
878    fn from_inner(inner: &Slice) -> &OsStr {
879        // SAFETY: OsStr is just a wrapper of Slice,
880        // therefore converting &Slice to &OsStr is safe.
881        unsafe { &*(inner as *const Slice as *const OsStr) }
882    }
883
884    #[inline]
885    fn from_inner_mut(inner: &mut Slice) -> &mut OsStr {
886        // SAFETY: OsStr is just a wrapper of Slice,
887        // therefore converting &mut Slice to &mut OsStr is safe.
888        // Any method that mutates OsStr must be careful not to
889        // break platform-specific encoding, in particular Wtf8 on Windows.
890        unsafe { &mut *(inner as *mut Slice as *mut OsStr) }
891    }
892
893    /// Yields a <code>&[str]</code> slice if the `OsStr` is valid Unicode.
894    ///
895    /// This conversion may entail doing a check for UTF-8 validity.
896    ///
897    /// # Examples
898    ///
899    /// ```
900    /// use std::ffi::OsStr;
901    ///
902    /// let os_str = OsStr::new("foo");
903    /// assert_eq!(os_str.to_str(), Some("foo"));
904    /// ```
905    #[stable(feature = "rust1", since = "1.0.0")]
906    #[must_use = "this returns the result of the operation, \
907                  without modifying the original"]
908    #[inline]
909    pub fn to_str(&self) -> Option<&str> {
910        self.inner.to_str().ok()
911    }
912
913    /// Converts an `OsStr` to a <code>[Cow]<[str]></code>.
914    ///
915    /// Any non-UTF-8 sequences are replaced with
916    /// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD].
917    ///
918    /// [U+FFFD]: crate::char::REPLACEMENT_CHARACTER
919    ///
920    /// # Examples
921    ///
922    /// Calling `to_string_lossy` on an `OsStr` with invalid unicode:
923    ///
924    /// ```
925    /// // Note, due to differences in how Unix and Windows represent strings,
926    /// // we are forced to complicate this example, setting up example `OsStr`s
927    /// // with different source data and via different platform extensions.
928    /// // Understand that in reality you could end up with such example invalid
929    /// // sequences simply through collecting user command line arguments, for
930    /// // example.
931    ///
932    /// #[cfg(unix)] {
933    ///     use std::ffi::OsStr;
934    ///     use std::os::unix::ffi::OsStrExt;
935    ///
936    ///     // Here, the values 0x66 and 0x6f correspond to 'f' and 'o'
937    ///     // respectively. The value 0x80 is a lone continuation byte, invalid
938    ///     // in a UTF-8 sequence.
939    ///     let source = [0x66, 0x6f, 0x80, 0x6f];
940    ///     let os_str = OsStr::from_bytes(&source[..]);
941    ///
942    ///     assert_eq!(os_str.to_string_lossy(), "fo�o");
943    /// }
944    /// #[cfg(windows)] {
945    ///     use std::ffi::OsString;
946    ///     use std::os::windows::prelude::*;
947    ///
948    ///     // Here the values 0x0066 and 0x006f correspond to 'f' and 'o'
949    ///     // respectively. The value 0xD800 is a lone surrogate half, invalid
950    ///     // in a UTF-16 sequence.
951    ///     let source = [0x0066, 0x006f, 0xD800, 0x006f];
952    ///     let os_string = OsString::from_wide(&source[..]);
953    ///     let os_str = os_string.as_os_str();
954    ///
955    ///     assert_eq!(os_str.to_string_lossy(), "fo�o");
956    /// }
957    /// ```
958    #[stable(feature = "rust1", since = "1.0.0")]
959    #[must_use = "this returns the result of the operation, \
960                  without modifying the original"]
961    #[inline]
962    pub fn to_string_lossy(&self) -> Cow<'_, str> {
963        self.inner.to_string_lossy()
964    }
965
966    /// Copies the slice into an owned [`OsString`].
967    ///
968    /// # Examples
969    ///
970    /// ```
971    /// use std::ffi::{OsStr, OsString};
972    ///
973    /// let os_str = OsStr::new("foo");
974    /// let os_string = os_str.to_os_string();
975    /// assert_eq!(os_string, OsString::from("foo"));
976    /// ```
977    #[stable(feature = "rust1", since = "1.0.0")]
978    #[must_use = "this returns the result of the operation, \
979                  without modifying the original"]
980    #[inline]
981    #[cfg_attr(not(test), rustc_diagnostic_item = "os_str_to_os_string")]
982    pub fn to_os_string(&self) -> OsString {
983        OsString { inner: self.inner.to_owned() }
984    }
985
986    /// Checks whether the `OsStr` is empty.
987    ///
988    /// # Examples
989    ///
990    /// ```
991    /// use std::ffi::OsStr;
992    ///
993    /// let os_str = OsStr::new("");
994    /// assert!(os_str.is_empty());
995    ///
996    /// let os_str = OsStr::new("foo");
997    /// assert!(!os_str.is_empty());
998    /// ```
999    #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
1000    #[must_use]
1001    #[inline]
1002    pub fn is_empty(&self) -> bool {
1003        self.inner.inner.is_empty()
1004    }
1005
1006    /// Returns the length of this `OsStr`.
1007    ///
1008    /// Note that this does **not** return the number of bytes in the string in
1009    /// OS string form.
1010    ///
1011    /// The length returned is that of the underlying storage used by `OsStr`.
1012    /// As discussed in the [`OsString`] introduction, [`OsString`] and `OsStr`
1013    /// store strings in a form best suited for cheap inter-conversion between
1014    /// native-platform and Rust string forms, which may differ significantly
1015    /// from both of them, including in storage size and encoding.
1016    ///
1017    /// This number is simply useful for passing to other methods, like
1018    /// [`OsString::with_capacity`] to avoid reallocations.
1019    ///
1020    /// See the main `OsString` documentation information about encoding and capacity units.
1021    ///
1022    /// # Examples
1023    ///
1024    /// ```
1025    /// use std::ffi::OsStr;
1026    ///
1027    /// let os_str = OsStr::new("");
1028    /// assert_eq!(os_str.len(), 0);
1029    ///
1030    /// let os_str = OsStr::new("foo");
1031    /// assert_eq!(os_str.len(), 3);
1032    /// ```
1033    #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
1034    #[must_use]
1035    #[inline]
1036    pub fn len(&self) -> usize {
1037        self.inner.inner.len()
1038    }
1039
1040    /// Converts a <code>[Box]<[OsStr]></code> into an [`OsString`] without copying or allocating.
1041    #[stable(feature = "into_boxed_os_str", since = "1.20.0")]
1042    #[must_use = "`self` will be dropped if the result is not used"]
1043    pub fn into_os_string(self: Box<OsStr>) -> OsString {
1044        let boxed = unsafe { Box::from_raw(Box::into_raw(self) as *mut Slice) };
1045        OsString { inner: Buf::from_box(boxed) }
1046    }
1047
1048    /// Converts an OS string slice to a byte slice.  To convert the byte slice back into an OS
1049    /// string slice, use the [`OsStr::from_encoded_bytes_unchecked`] function.
1050    ///
1051    /// The byte encoding is an unspecified, platform-specific, self-synchronizing superset of UTF-8.
1052    /// By being a self-synchronizing superset of UTF-8, this encoding is also a superset of 7-bit
1053    /// ASCII.
1054    ///
1055    /// Note: As the encoding is unspecified, any sub-slice of bytes that is not valid UTF-8 should
1056    /// be treated as opaque and only comparable within the same Rust version built for the same
1057    /// target platform.  For example, sending the slice over the network or storing it in a file
1058    /// will likely result in incompatible byte slices.  See [`OsString`] for more encoding details
1059    /// and [`std::ffi`] for platform-specific, specified conversions.
1060    ///
1061    /// [`std::ffi`]: crate::ffi
1062    #[inline]
1063    #[stable(feature = "os_str_bytes", since = "1.74.0")]
1064    pub fn as_encoded_bytes(&self) -> &[u8] {
1065        self.inner.as_encoded_bytes()
1066    }
1067
1068    /// Takes a substring based on a range that corresponds to the return value of
1069    /// [`OsStr::as_encoded_bytes`].
1070    ///
1071    /// The range's start and end must lie on valid `OsStr` boundaries.
1072    /// A valid `OsStr` boundary is one of:
1073    /// - The start of the string
1074    /// - The end of the string
1075    /// - Immediately before a valid non-empty UTF-8 substring
1076    /// - Immediately after a valid non-empty UTF-8 substring
1077    ///
1078    /// # Panics
1079    ///
1080    /// Panics if `range` does not lie on valid `OsStr` boundaries or if it
1081    /// exceeds the end of the string.
1082    ///
1083    /// # Example
1084    ///
1085    /// ```
1086    /// #![feature(os_str_slice)]
1087    ///
1088    /// use std::ffi::OsStr;
1089    ///
1090    /// let os_str = OsStr::new("foo=bar");
1091    /// let bytes = os_str.as_encoded_bytes();
1092    /// if let Some(index) = bytes.iter().position(|b| *b == b'=') {
1093    ///     let key = os_str.slice_encoded_bytes(..index);
1094    ///     let value = os_str.slice_encoded_bytes(index + 1..);
1095    ///     assert_eq!(key, "foo");
1096    ///     assert_eq!(value, "bar");
1097    /// }
1098    /// ```
1099    #[unstable(feature = "os_str_slice", issue = "118485")]
1100    pub fn slice_encoded_bytes<R: ops::RangeBounds<usize>>(&self, range: R) -> &Self {
1101        let encoded_bytes = self.as_encoded_bytes();
1102        let Range { start, end } = slice::range(range, ..encoded_bytes.len());
1103
1104        // `check_public_boundary` should panic if the index does not lie on an
1105        // `OsStr` boundary as described above. It's possible to do this in an
1106        // encoding-agnostic way, but details of the internal encoding might
1107        // permit a more efficient implementation.
1108        self.inner.check_public_boundary(start);
1109        self.inner.check_public_boundary(end);
1110
1111        // SAFETY: `slice::range` ensures that `start` and `end` are valid
1112        let slice = unsafe { encoded_bytes.get_unchecked(start..end) };
1113
1114        // SAFETY: `slice` comes from `self` and we validated the boundaries
1115        unsafe { Self::from_encoded_bytes_unchecked(slice) }
1116    }
1117
1118    /// Converts this string to its ASCII lower case equivalent in-place.
1119    ///
1120    /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
1121    /// but non-ASCII letters are unchanged.
1122    ///
1123    /// To return a new lowercased value without modifying the existing one, use
1124    /// [`OsStr::to_ascii_lowercase`].
1125    ///
1126    /// # Examples
1127    ///
1128    /// ```
1129    /// use std::ffi::OsString;
1130    ///
1131    /// let mut s = OsString::from("GRÜßE, JÜRGEN ❤");
1132    ///
1133    /// s.make_ascii_lowercase();
1134    ///
1135    /// assert_eq!("grÜße, jÜrgen ❤", s);
1136    /// ```
1137    #[stable(feature = "osstring_ascii", since = "1.53.0")]
1138    #[inline]
1139    pub fn make_ascii_lowercase(&mut self) {
1140        self.inner.make_ascii_lowercase()
1141    }
1142
1143    /// Converts this string to its ASCII upper case equivalent in-place.
1144    ///
1145    /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
1146    /// but non-ASCII letters are unchanged.
1147    ///
1148    /// To return a new uppercased value without modifying the existing one, use
1149    /// [`OsStr::to_ascii_uppercase`].
1150    ///
1151    /// # Examples
1152    ///
1153    /// ```
1154    /// use std::ffi::OsString;
1155    ///
1156    /// let mut s = OsString::from("Grüße, Jürgen ❤");
1157    ///
1158    /// s.make_ascii_uppercase();
1159    ///
1160    /// assert_eq!("GRüßE, JüRGEN ❤", s);
1161    /// ```
1162    #[stable(feature = "osstring_ascii", since = "1.53.0")]
1163    #[inline]
1164    pub fn make_ascii_uppercase(&mut self) {
1165        self.inner.make_ascii_uppercase()
1166    }
1167
1168    /// Returns a copy of this string where each character is mapped to its
1169    /// ASCII lower case equivalent.
1170    ///
1171    /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
1172    /// but non-ASCII letters are unchanged.
1173    ///
1174    /// To lowercase the value in-place, use [`OsStr::make_ascii_lowercase`].
1175    ///
1176    /// # Examples
1177    ///
1178    /// ```
1179    /// use std::ffi::OsString;
1180    /// let s = OsString::from("Grüße, Jürgen ❤");
1181    ///
1182    /// assert_eq!("grüße, jürgen ❤", s.to_ascii_lowercase());
1183    /// ```
1184    #[must_use = "to lowercase the value in-place, use `make_ascii_lowercase`"]
1185    #[stable(feature = "osstring_ascii", since = "1.53.0")]
1186    pub fn to_ascii_lowercase(&self) -> OsString {
1187        OsString::from_inner(self.inner.to_ascii_lowercase())
1188    }
1189
1190    /// Returns a copy of this string where each character is mapped to its
1191    /// ASCII upper case equivalent.
1192    ///
1193    /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
1194    /// but non-ASCII letters are unchanged.
1195    ///
1196    /// To uppercase the value in-place, use [`OsStr::make_ascii_uppercase`].
1197    ///
1198    /// # Examples
1199    ///
1200    /// ```
1201    /// use std::ffi::OsString;
1202    /// let s = OsString::from("Grüße, Jürgen ❤");
1203    ///
1204    /// assert_eq!("GRüßE, JüRGEN ❤", s.to_ascii_uppercase());
1205    /// ```
1206    #[must_use = "to uppercase the value in-place, use `make_ascii_uppercase`"]
1207    #[stable(feature = "osstring_ascii", since = "1.53.0")]
1208    pub fn to_ascii_uppercase(&self) -> OsString {
1209        OsString::from_inner(self.inner.to_ascii_uppercase())
1210    }
1211
1212    /// Checks if all characters in this string are within the ASCII range.
1213    ///
1214    /// # Examples
1215    ///
1216    /// ```
1217    /// use std::ffi::OsString;
1218    ///
1219    /// let ascii = OsString::from("hello!\n");
1220    /// let non_ascii = OsString::from("Grüße, Jürgen ❤");
1221    ///
1222    /// assert!(ascii.is_ascii());
1223    /// assert!(!non_ascii.is_ascii());
1224    /// ```
1225    #[stable(feature = "osstring_ascii", since = "1.53.0")]
1226    #[must_use]
1227    #[inline]
1228    pub fn is_ascii(&self) -> bool {
1229        self.inner.is_ascii()
1230    }
1231
1232    /// Checks that two strings are an ASCII case-insensitive match.
1233    ///
1234    /// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`,
1235    /// but without allocating and copying temporaries.
1236    ///
1237    /// # Examples
1238    ///
1239    /// ```
1240    /// use std::ffi::OsString;
1241    ///
1242    /// assert!(OsString::from("Ferris").eq_ignore_ascii_case("FERRIS"));
1243    /// assert!(OsString::from("Ferrös").eq_ignore_ascii_case("FERRöS"));
1244    /// assert!(!OsString::from("Ferrös").eq_ignore_ascii_case("FERRÖS"));
1245    /// ```
1246    #[stable(feature = "osstring_ascii", since = "1.53.0")]
1247    pub fn eq_ignore_ascii_case<S: AsRef<OsStr>>(&self, other: S) -> bool {
1248        self.inner.eq_ignore_ascii_case(&other.as_ref().inner)
1249    }
1250
1251    /// Returns an object that implements [`Display`] for safely printing an
1252    /// [`OsStr`] that may contain non-Unicode data. This may perform lossy
1253    /// conversion, depending on the platform.  If you would like an
1254    /// implementation which escapes the [`OsStr`] please use [`Debug`]
1255    /// instead.
1256    ///
1257    /// [`Display`]: fmt::Display
1258    /// [`Debug`]: fmt::Debug
1259    ///
1260    /// # Examples
1261    ///
1262    /// ```
1263    /// use std::ffi::OsStr;
1264    ///
1265    /// let s = OsStr::new("Hello, world!");
1266    /// println!("{}", s.display());
1267    /// ```
1268    #[stable(feature = "os_str_display", since = "1.87.0")]
1269    #[must_use = "this does not display the `OsStr`; \
1270                  it returns an object that can be displayed"]
1271    #[inline]
1272    pub fn display(&self) -> Display<'_> {
1273        Display { os_str: self }
1274    }
1275}
1276
1277#[stable(feature = "box_from_os_str", since = "1.17.0")]
1278impl From<&OsStr> for Box<OsStr> {
1279    /// Copies the string into a newly allocated <code>[Box]&lt;[OsStr]&gt;</code>.
1280    #[inline]
1281    fn from(s: &OsStr) -> Box<OsStr> {
1282        let rw = Box::into_raw(s.inner.into_box()) as *mut OsStr;
1283        unsafe { Box::from_raw(rw) }
1284    }
1285}
1286
1287#[stable(feature = "box_from_mut_slice", since = "1.84.0")]
1288impl From<&mut OsStr> for Box<OsStr> {
1289    /// Copies the string into a newly allocated <code>[Box]&lt;[OsStr]&gt;</code>.
1290    #[inline]
1291    fn from(s: &mut OsStr) -> Box<OsStr> {
1292        Self::from(&*s)
1293    }
1294}
1295
1296#[stable(feature = "box_from_cow", since = "1.45.0")]
1297impl From<Cow<'_, OsStr>> for Box<OsStr> {
1298    /// Converts a `Cow<'a, OsStr>` into a <code>[Box]&lt;[OsStr]&gt;</code>,
1299    /// by copying the contents if they are borrowed.
1300    #[inline]
1301    fn from(cow: Cow<'_, OsStr>) -> Box<OsStr> {
1302        match cow {
1303            Cow::Borrowed(s) => Box::from(s),
1304            Cow::Owned(s) => Box::from(s),
1305        }
1306    }
1307}
1308
1309#[stable(feature = "os_string_from_box", since = "1.18.0")]
1310impl From<Box<OsStr>> for OsString {
1311    /// Converts a <code>[Box]<[OsStr]></code> into an [`OsString`] without copying or
1312    /// allocating.
1313    #[inline]
1314    fn from(boxed: Box<OsStr>) -> OsString {
1315        boxed.into_os_string()
1316    }
1317}
1318
1319#[stable(feature = "box_from_os_string", since = "1.20.0")]
1320impl From<OsString> for Box<OsStr> {
1321    /// Converts an [`OsString`] into a <code>[Box]<[OsStr]></code> without copying or allocating.
1322    #[inline]
1323    fn from(s: OsString) -> Box<OsStr> {
1324        s.into_boxed_os_str()
1325    }
1326}
1327
1328#[stable(feature = "more_box_slice_clone", since = "1.29.0")]
1329impl Clone for Box<OsStr> {
1330    #[inline]
1331    fn clone(&self) -> Self {
1332        self.to_os_string().into_boxed_os_str()
1333    }
1334}
1335
1336#[unstable(feature = "clone_to_uninit", issue = "126799")]
1337unsafe impl CloneToUninit for OsStr {
1338    #[inline]
1339    #[cfg_attr(debug_assertions, track_caller)]
1340    unsafe fn clone_to_uninit(&self, dst: *mut u8) {
1341        // SAFETY: we're just a transparent wrapper around a platform-specific Slice
1342        unsafe { self.inner.clone_to_uninit(dst) }
1343    }
1344}
1345
1346#[stable(feature = "shared_from_slice2", since = "1.24.0")]
1347impl From<OsString> for Arc<OsStr> {
1348    /// Converts an [`OsString`] into an <code>[Arc]<[OsStr]></code> by moving the [`OsString`]
1349    /// data into a new [`Arc`] buffer.
1350    #[inline]
1351    fn from(s: OsString) -> Arc<OsStr> {
1352        let arc = s.inner.into_arc();
1353        unsafe { Arc::from_raw(Arc::into_raw(arc) as *const OsStr) }
1354    }
1355}
1356
1357#[stable(feature = "shared_from_slice2", since = "1.24.0")]
1358impl From<&OsStr> for Arc<OsStr> {
1359    /// Copies the string into a newly allocated <code>[Arc]&lt;[OsStr]&gt;</code>.
1360    #[inline]
1361    fn from(s: &OsStr) -> Arc<OsStr> {
1362        let arc = s.inner.into_arc();
1363        unsafe { Arc::from_raw(Arc::into_raw(arc) as *const OsStr) }
1364    }
1365}
1366
1367#[stable(feature = "shared_from_mut_slice", since = "1.84.0")]
1368impl From<&mut OsStr> for Arc<OsStr> {
1369    /// Copies the string into a newly allocated <code>[Arc]&lt;[OsStr]&gt;</code>.
1370    #[inline]
1371    fn from(s: &mut OsStr) -> Arc<OsStr> {
1372        Arc::from(&*s)
1373    }
1374}
1375
1376#[stable(feature = "shared_from_slice2", since = "1.24.0")]
1377impl From<OsString> for Rc<OsStr> {
1378    /// Converts an [`OsString`] into an <code>[Rc]<[OsStr]></code> by moving the [`OsString`]
1379    /// data into a new [`Rc`] buffer.
1380    #[inline]
1381    fn from(s: OsString) -> Rc<OsStr> {
1382        let rc = s.inner.into_rc();
1383        unsafe { Rc::from_raw(Rc::into_raw(rc) as *const OsStr) }
1384    }
1385}
1386
1387#[stable(feature = "shared_from_slice2", since = "1.24.0")]
1388impl From<&OsStr> for Rc<OsStr> {
1389    /// Copies the string into a newly allocated <code>[Rc]&lt;[OsStr]&gt;</code>.
1390    #[inline]
1391    fn from(s: &OsStr) -> Rc<OsStr> {
1392        let rc = s.inner.into_rc();
1393        unsafe { Rc::from_raw(Rc::into_raw(rc) as *const OsStr) }
1394    }
1395}
1396
1397#[stable(feature = "shared_from_mut_slice", since = "1.84.0")]
1398impl From<&mut OsStr> for Rc<OsStr> {
1399    /// Copies the string into a newly allocated <code>[Rc]&lt;[OsStr]&gt;</code>.
1400    #[inline]
1401    fn from(s: &mut OsStr) -> Rc<OsStr> {
1402        Rc::from(&*s)
1403    }
1404}
1405
1406#[stable(feature = "cow_from_osstr", since = "1.28.0")]
1407impl<'a> From<OsString> for Cow<'a, OsStr> {
1408    /// Moves the string into a [`Cow::Owned`].
1409    #[inline]
1410    fn from(s: OsString) -> Cow<'a, OsStr> {
1411        Cow::Owned(s)
1412    }
1413}
1414
1415#[stable(feature = "cow_from_osstr", since = "1.28.0")]
1416impl<'a> From<&'a OsStr> for Cow<'a, OsStr> {
1417    /// Converts the string reference into a [`Cow::Borrowed`].
1418    #[inline]
1419    fn from(s: &'a OsStr) -> Cow<'a, OsStr> {
1420        Cow::Borrowed(s)
1421    }
1422}
1423
1424#[stable(feature = "cow_from_osstr", since = "1.28.0")]
1425impl<'a> From<&'a OsString> for Cow<'a, OsStr> {
1426    /// Converts the string reference into a [`Cow::Borrowed`].
1427    #[inline]
1428    fn from(s: &'a OsString) -> Cow<'a, OsStr> {
1429        Cow::Borrowed(s.as_os_str())
1430    }
1431}
1432
1433#[stable(feature = "osstring_from_cow_osstr", since = "1.28.0")]
1434impl<'a> From<Cow<'a, OsStr>> for OsString {
1435    /// Converts a `Cow<'a, OsStr>` into an [`OsString`],
1436    /// by copying the contents if they are borrowed.
1437    #[inline]
1438    fn from(s: Cow<'a, OsStr>) -> Self {
1439        s.into_owned()
1440    }
1441}
1442
1443#[stable(feature = "str_tryfrom_osstr_impl", since = "1.72.0")]
1444impl<'a> TryFrom<&'a OsStr> for &'a str {
1445    type Error = crate::str::Utf8Error;
1446
1447    /// Tries to convert an `&OsStr` to a `&str`.
1448    ///
1449    /// ```
1450    /// use std::ffi::OsStr;
1451    ///
1452    /// let os_str = OsStr::new("foo");
1453    /// let as_str = <&str>::try_from(os_str).unwrap();
1454    /// assert_eq!(as_str, "foo");
1455    /// ```
1456    fn try_from(value: &'a OsStr) -> Result<Self, Self::Error> {
1457        value.inner.to_str()
1458    }
1459}
1460
1461#[stable(feature = "box_default_extra", since = "1.17.0")]
1462impl Default for Box<OsStr> {
1463    #[inline]
1464    fn default() -> Box<OsStr> {
1465        let rw = Box::into_raw(Slice::empty_box()) as *mut OsStr;
1466        unsafe { Box::from_raw(rw) }
1467    }
1468}
1469
1470#[stable(feature = "osstring_default", since = "1.9.0")]
1471impl Default for &OsStr {
1472    /// Creates an empty `OsStr`.
1473    #[inline]
1474    fn default() -> Self {
1475        OsStr::new("")
1476    }
1477}
1478
1479#[stable(feature = "rust1", since = "1.0.0")]
1480impl PartialEq for OsStr {
1481    #[inline]
1482    fn eq(&self, other: &OsStr) -> bool {
1483        self.as_encoded_bytes().eq(other.as_encoded_bytes())
1484    }
1485}
1486
1487#[stable(feature = "rust1", since = "1.0.0")]
1488impl PartialEq<str> for OsStr {
1489    #[inline]
1490    fn eq(&self, other: &str) -> bool {
1491        *self == *OsStr::new(other)
1492    }
1493}
1494
1495#[stable(feature = "rust1", since = "1.0.0")]
1496impl PartialEq<OsStr> for str {
1497    #[inline]
1498    fn eq(&self, other: &OsStr) -> bool {
1499        *other == *OsStr::new(self)
1500    }
1501}
1502
1503#[stable(feature = "rust1", since = "1.0.0")]
1504impl Eq for OsStr {}
1505
1506#[stable(feature = "rust1", since = "1.0.0")]
1507impl PartialOrd for OsStr {
1508    #[inline]
1509    fn partial_cmp(&self, other: &OsStr) -> Option<cmp::Ordering> {
1510        self.as_encoded_bytes().partial_cmp(other.as_encoded_bytes())
1511    }
1512    #[inline]
1513    fn lt(&self, other: &OsStr) -> bool {
1514        self.as_encoded_bytes().lt(other.as_encoded_bytes())
1515    }
1516    #[inline]
1517    fn le(&self, other: &OsStr) -> bool {
1518        self.as_encoded_bytes().le(other.as_encoded_bytes())
1519    }
1520    #[inline]
1521    fn gt(&self, other: &OsStr) -> bool {
1522        self.as_encoded_bytes().gt(other.as_encoded_bytes())
1523    }
1524    #[inline]
1525    fn ge(&self, other: &OsStr) -> bool {
1526        self.as_encoded_bytes().ge(other.as_encoded_bytes())
1527    }
1528}
1529
1530#[stable(feature = "rust1", since = "1.0.0")]
1531impl PartialOrd<str> for OsStr {
1532    #[inline]
1533    fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
1534        self.partial_cmp(OsStr::new(other))
1535    }
1536}
1537
1538// FIXME (#19470): cannot provide PartialOrd<OsStr> for str until we
1539// have more flexible coherence rules.
1540
1541#[stable(feature = "rust1", since = "1.0.0")]
1542impl Ord for OsStr {
1543    #[inline]
1544    fn cmp(&self, other: &OsStr) -> cmp::Ordering {
1545        self.as_encoded_bytes().cmp(other.as_encoded_bytes())
1546    }
1547}
1548
1549macro_rules! impl_cmp {
1550    ($lhs:ty, $rhs: ty) => {
1551        #[stable(feature = "cmp_os_str", since = "1.8.0")]
1552        impl<'a, 'b> PartialEq<$rhs> for $lhs {
1553            #[inline]
1554            fn eq(&self, other: &$rhs) -> bool {
1555                <OsStr as PartialEq>::eq(self, other)
1556            }
1557        }
1558
1559        #[stable(feature = "cmp_os_str", since = "1.8.0")]
1560        impl<'a, 'b> PartialEq<$lhs> for $rhs {
1561            #[inline]
1562            fn eq(&self, other: &$lhs) -> bool {
1563                <OsStr as PartialEq>::eq(self, other)
1564            }
1565        }
1566
1567        #[stable(feature = "cmp_os_str", since = "1.8.0")]
1568        impl<'a, 'b> PartialOrd<$rhs> for $lhs {
1569            #[inline]
1570            fn partial_cmp(&self, other: &$rhs) -> Option<cmp::Ordering> {
1571                <OsStr as PartialOrd>::partial_cmp(self, other)
1572            }
1573        }
1574
1575        #[stable(feature = "cmp_os_str", since = "1.8.0")]
1576        impl<'a, 'b> PartialOrd<$lhs> for $rhs {
1577            #[inline]
1578            fn partial_cmp(&self, other: &$lhs) -> Option<cmp::Ordering> {
1579                <OsStr as PartialOrd>::partial_cmp(self, other)
1580            }
1581        }
1582    };
1583}
1584
1585impl_cmp!(OsString, OsStr);
1586impl_cmp!(OsString, &'a OsStr);
1587impl_cmp!(Cow<'a, OsStr>, OsStr);
1588impl_cmp!(Cow<'a, OsStr>, &'b OsStr);
1589impl_cmp!(Cow<'a, OsStr>, OsString);
1590
1591#[stable(feature = "rust1", since = "1.0.0")]
1592impl Hash for OsStr {
1593    #[inline]
1594    fn hash<H: Hasher>(&self, state: &mut H) {
1595        self.as_encoded_bytes().hash(state)
1596    }
1597}
1598
1599#[stable(feature = "rust1", since = "1.0.0")]
1600impl fmt::Debug for OsStr {
1601    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1602        fmt::Debug::fmt(&self.inner, formatter)
1603    }
1604}
1605
1606/// Helper struct for safely printing an [`OsStr`] with [`format!`] and `{}`.
1607///
1608/// An [`OsStr`] might contain non-Unicode data. This `struct` implements the
1609/// [`Display`] trait in a way that mitigates that. It is created by the
1610/// [`display`](OsStr::display) method on [`OsStr`]. This may perform lossy
1611/// conversion, depending on the platform. If you would like an implementation
1612/// which escapes the [`OsStr`] please use [`Debug`] instead.
1613///
1614/// # Examples
1615///
1616/// ```
1617/// use std::ffi::OsStr;
1618///
1619/// let s = OsStr::new("Hello, world!");
1620/// println!("{}", s.display());
1621/// ```
1622///
1623/// [`Display`]: fmt::Display
1624/// [`format!`]: crate::format
1625#[stable(feature = "os_str_display", since = "1.87.0")]
1626pub struct Display<'a> {
1627    os_str: &'a OsStr,
1628}
1629
1630#[stable(feature = "os_str_display", since = "1.87.0")]
1631impl fmt::Debug for Display<'_> {
1632    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1633        fmt::Debug::fmt(&self.os_str, f)
1634    }
1635}
1636
1637#[stable(feature = "os_str_display", since = "1.87.0")]
1638impl fmt::Display for Display<'_> {
1639    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1640        fmt::Display::fmt(&self.os_str.inner, f)
1641    }
1642}
1643
1644#[unstable(feature = "slice_concat_ext", issue = "27747")]
1645impl<S: Borrow<OsStr>> alloc::slice::Join<&OsStr> for [S] {
1646    type Output = OsString;
1647
1648    fn join(slice: &Self, sep: &OsStr) -> OsString {
1649        let Some((first, suffix)) = slice.split_first() else {
1650            return OsString::new();
1651        };
1652        let first_owned = first.borrow().to_owned();
1653        suffix.iter().fold(first_owned, |mut a, b| {
1654            a.push(sep);
1655            a.push(b.borrow());
1656            a
1657        })
1658    }
1659}
1660
1661#[stable(feature = "rust1", since = "1.0.0")]
1662impl Borrow<OsStr> for OsString {
1663    #[inline]
1664    fn borrow(&self) -> &OsStr {
1665        &self[..]
1666    }
1667}
1668
1669#[stable(feature = "rust1", since = "1.0.0")]
1670impl ToOwned for OsStr {
1671    type Owned = OsString;
1672    #[inline]
1673    fn to_owned(&self) -> OsString {
1674        self.to_os_string()
1675    }
1676    #[inline]
1677    fn clone_into(&self, target: &mut OsString) {
1678        self.inner.clone_into(&mut target.inner)
1679    }
1680}
1681
1682#[stable(feature = "rust1", since = "1.0.0")]
1683impl AsRef<OsStr> for OsStr {
1684    #[inline]
1685    fn as_ref(&self) -> &OsStr {
1686        self
1687    }
1688}
1689
1690#[stable(feature = "rust1", since = "1.0.0")]
1691impl AsRef<OsStr> for OsString {
1692    #[inline]
1693    fn as_ref(&self) -> &OsStr {
1694        self
1695    }
1696}
1697
1698#[stable(feature = "rust1", since = "1.0.0")]
1699impl AsRef<OsStr> for str {
1700    #[inline]
1701    fn as_ref(&self) -> &OsStr {
1702        OsStr::from_inner(Slice::from_str(self))
1703    }
1704}
1705
1706#[stable(feature = "rust1", since = "1.0.0")]
1707impl AsRef<OsStr> for String {
1708    #[inline]
1709    fn as_ref(&self) -> &OsStr {
1710        (&**self).as_ref()
1711    }
1712}
1713
1714impl FromInner<Buf> for OsString {
1715    #[inline]
1716    fn from_inner(buf: Buf) -> OsString {
1717        OsString { inner: buf }
1718    }
1719}
1720
1721impl IntoInner<Buf> for OsString {
1722    #[inline]
1723    fn into_inner(self) -> Buf {
1724        self.inner
1725    }
1726}
1727
1728impl AsInner<Slice> for OsStr {
1729    #[inline]
1730    fn as_inner(&self) -> &Slice {
1731        &self.inner
1732    }
1733}
1734
1735#[stable(feature = "osstring_from_str", since = "1.45.0")]
1736impl FromStr for OsString {
1737    type Err = core::convert::Infallible;
1738
1739    #[inline]
1740    fn from_str(s: &str) -> Result<Self, Self::Err> {
1741        Ok(OsString::from(s))
1742    }
1743}
1744
1745#[stable(feature = "osstring_extend", since = "1.52.0")]
1746impl Extend<OsString> for OsString {
1747    #[inline]
1748    fn extend<T: IntoIterator<Item = OsString>>(&mut self, iter: T) {
1749        for s in iter {
1750            self.push(&s);
1751        }
1752    }
1753}
1754
1755#[stable(feature = "osstring_extend", since = "1.52.0")]
1756impl<'a> Extend<&'a OsStr> for OsString {
1757    #[inline]
1758    fn extend<T: IntoIterator<Item = &'a OsStr>>(&mut self, iter: T) {
1759        for s in iter {
1760            self.push(s);
1761        }
1762    }
1763}
1764
1765#[stable(feature = "osstring_extend", since = "1.52.0")]
1766impl<'a> Extend<Cow<'a, OsStr>> for OsString {
1767    #[inline]
1768    fn extend<T: IntoIterator<Item = Cow<'a, OsStr>>>(&mut self, iter: T) {
1769        for s in iter {
1770            self.push(&s);
1771        }
1772    }
1773}
1774
1775#[stable(feature = "osstring_extend", since = "1.52.0")]
1776impl FromIterator<OsString> for OsString {
1777    #[inline]
1778    fn from_iter<I: IntoIterator<Item = OsString>>(iter: I) -> Self {
1779        let mut iterator = iter.into_iter();
1780
1781        // Because we're iterating over `OsString`s, we can avoid at least
1782        // one allocation by getting the first string from the iterator
1783        // and appending to it all the subsequent strings.
1784        match iterator.next() {
1785            None => OsString::new(),
1786            Some(mut buf) => {
1787                buf.extend(iterator);
1788                buf
1789            }
1790        }
1791    }
1792}
1793
1794#[stable(feature = "osstring_extend", since = "1.52.0")]
1795impl<'a> FromIterator<&'a OsStr> for OsString {
1796    #[inline]
1797    fn from_iter<I: IntoIterator<Item = &'a OsStr>>(iter: I) -> Self {
1798        let mut buf = Self::new();
1799        for s in iter {
1800            buf.push(s);
1801        }
1802        buf
1803    }
1804}
1805
1806#[stable(feature = "osstring_extend", since = "1.52.0")]
1807impl<'a> FromIterator<Cow<'a, OsStr>> for OsString {
1808    #[inline]
1809    fn from_iter<I: IntoIterator<Item = Cow<'a, OsStr>>>(iter: I) -> Self {
1810        let mut iterator = iter.into_iter();
1811
1812        // Because we're iterating over `OsString`s, we can avoid at least
1813        // one allocation by getting the first owned string from the iterator
1814        // and appending to it all the subsequent strings.
1815        match iterator.next() {
1816            None => OsString::new(),
1817            Some(Cow::Owned(mut buf)) => {
1818                buf.extend(iterator);
1819                buf
1820            }
1821            Some(Cow::Borrowed(buf)) => {
1822                let mut buf = OsString::from(buf);
1823                buf.extend(iterator);
1824                buf
1825            }
1826        }
1827    }
1828}