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