Skip to main content

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