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 the string's current length, this has no
573    /// 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            self.as_os_str().inner.check_public_boundary(len);
584            // SAFETY: The length was just checked to be at a valid boundary.
585            unsafe { self.inner.truncate_unchecked(len) };
586        }
587    }
588
589    /// Provides plumbing to `Vec::extend_from_slice` without giving full
590    /// mutable access to the `Vec`.
591    ///
592    /// # Safety
593    ///
594    /// The slice must be valid for the platform encoding (as described in
595    /// [`OsStr::from_encoded_bytes_unchecked`]).
596    ///
597    /// This bypasses the encoding-dependent surrogate joining, so either
598    /// `self` must not end with a leading surrogate half, or `other` must not
599    /// start with a trailing surrogate half.
600    #[inline]
601    pub(crate) unsafe fn extend_from_slice_unchecked(&mut self, other: &[u8]) {
602        // SAFETY: Guaranteed by caller.
603        unsafe { self.inner.extend_from_slice_unchecked(other) };
604    }
605}
606
607#[stable(feature = "rust1", since = "1.0.0")]
608impl From<String> for OsString {
609    /// Converts a [`String`] into an [`OsString`].
610    ///
611    /// This conversion does not allocate or copy memory.
612    #[inline]
613    fn from(s: String) -> OsString {
614        OsString { inner: Buf::from_string(s) }
615    }
616}
617
618#[stable(feature = "rust1", since = "1.0.0")]
619impl<T: ?Sized + AsRef<OsStr>> From<&T> for OsString {
620    /// Copies any value implementing <code>[AsRef]&lt;[OsStr]&gt;</code>
621    /// into a newly allocated [`OsString`].
622    fn from(s: &T) -> OsString {
623        trait SpecToOsString {
624            fn spec_to_os_string(&self) -> OsString;
625        }
626
627        impl<T: AsRef<OsStr>> SpecToOsString for T {
628            #[inline]
629            default fn spec_to_os_string(&self) -> OsString {
630                self.as_ref().to_os_string()
631            }
632        }
633
634        // Preserve the known-UTF-8 property for strings.
635        macro spec_str($T:ty) {
636            impl SpecToOsString for $T {
637                #[inline]
638                fn spec_to_os_string(&self) -> OsString {
639                    OsString::from(String::from(self))
640                }
641            }
642        }
643        spec_str!(str);
644        spec_str!(String);
645
646        s.spec_to_os_string()
647    }
648}
649
650#[stable(feature = "rust1", since = "1.0.0")]
651impl ops::Index<ops::RangeFull> for OsString {
652    type Output = OsStr;
653
654    #[inline]
655    fn index(&self, _index: ops::RangeFull) -> &OsStr {
656        OsStr::from_inner(self.inner.as_slice())
657    }
658}
659
660#[stable(feature = "mut_osstr", since = "1.44.0")]
661impl ops::IndexMut<ops::RangeFull> for OsString {
662    #[inline]
663    fn index_mut(&mut self, _index: ops::RangeFull) -> &mut OsStr {
664        OsStr::from_inner_mut(self.inner.as_mut_slice())
665    }
666}
667
668#[stable(feature = "rust1", since = "1.0.0")]
669impl ops::Deref for OsString {
670    type Target = OsStr;
671
672    #[inline]
673    fn deref(&self) -> &OsStr {
674        &self[..]
675    }
676}
677
678#[stable(feature = "mut_osstr", since = "1.44.0")]
679impl ops::DerefMut for OsString {
680    #[inline]
681    fn deref_mut(&mut self) -> &mut OsStr {
682        &mut self[..]
683    }
684}
685
686#[stable(feature = "osstring_default", since = "1.9.0")]
687impl Default for OsString {
688    /// Constructs an empty `OsString`.
689    #[inline]
690    fn default() -> OsString {
691        OsString::new()
692    }
693}
694
695#[stable(feature = "rust1", since = "1.0.0")]
696impl Clone for OsString {
697    #[inline]
698    fn clone(&self) -> Self {
699        OsString { inner: self.inner.clone() }
700    }
701
702    /// Clones the contents of `source` into `self`.
703    ///
704    /// This method is preferred over simply assigning `source.clone()` to `self`,
705    /// as it avoids reallocation if possible.
706    #[inline]
707    fn clone_from(&mut self, source: &Self) {
708        self.inner.clone_from(&source.inner)
709    }
710}
711
712#[stable(feature = "rust1", since = "1.0.0")]
713impl fmt::Debug for OsString {
714    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
715        fmt::Debug::fmt(&**self, formatter)
716    }
717}
718
719#[stable(feature = "rust1", since = "1.0.0")]
720impl PartialEq for OsString {
721    #[inline]
722    fn eq(&self, other: &OsString) -> bool {
723        **self == **other
724    }
725}
726
727#[stable(feature = "rust1", since = "1.0.0")]
728impl PartialEq<str> for OsString {
729    #[inline]
730    fn eq(&self, other: &str) -> bool {
731        &**self == other
732    }
733}
734
735#[stable(feature = "rust1", since = "1.0.0")]
736impl PartialEq<OsString> for str {
737    #[inline]
738    fn eq(&self, other: &OsString) -> bool {
739        &**other == self
740    }
741}
742
743#[stable(feature = "os_str_str_ref_eq", since = "1.29.0")]
744impl PartialEq<&str> for OsString {
745    #[inline]
746    fn eq(&self, other: &&str) -> bool {
747        **self == **other
748    }
749}
750
751#[stable(feature = "os_str_str_ref_eq", since = "1.29.0")]
752impl<'a> PartialEq<OsString> for &'a str {
753    #[inline]
754    fn eq(&self, other: &OsString) -> bool {
755        **other == **self
756    }
757}
758
759#[stable(feature = "rust1", since = "1.0.0")]
760impl Eq for OsString {}
761
762#[stable(feature = "rust1", since = "1.0.0")]
763impl PartialOrd for OsString {
764    #[inline]
765    fn partial_cmp(&self, other: &OsString) -> Option<cmp::Ordering> {
766        (**self).partial_cmp(&**other)
767    }
768    #[inline]
769    fn lt(&self, other: &OsString) -> bool {
770        **self < **other
771    }
772    #[inline]
773    fn le(&self, other: &OsString) -> bool {
774        **self <= **other
775    }
776    #[inline]
777    fn gt(&self, other: &OsString) -> bool {
778        **self > **other
779    }
780    #[inline]
781    fn ge(&self, other: &OsString) -> bool {
782        **self >= **other
783    }
784}
785
786#[stable(feature = "rust1", since = "1.0.0")]
787impl PartialOrd<str> for OsString {
788    #[inline]
789    fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
790        (**self).partial_cmp(other)
791    }
792}
793
794#[stable(feature = "rust1", since = "1.0.0")]
795impl Ord for OsString {
796    #[inline]
797    fn cmp(&self, other: &OsString) -> cmp::Ordering {
798        (**self).cmp(&**other)
799    }
800}
801
802#[stable(feature = "rust1", since = "1.0.0")]
803impl Hash for OsString {
804    #[inline]
805    fn hash<H: Hasher>(&self, state: &mut H) {
806        (**self).hash(state)
807    }
808}
809
810#[stable(feature = "os_string_fmt_write", since = "1.64.0")]
811impl fmt::Write for OsString {
812    fn write_str(&mut self, s: &str) -> fmt::Result {
813        self.push(s);
814        Ok(())
815    }
816}
817
818impl OsStr {
819    /// Coerces into an `OsStr` slice.
820    ///
821    /// # Examples
822    ///
823    /// ```
824    /// use std::ffi::OsStr;
825    ///
826    /// let os_str = OsStr::new("foo");
827    /// ```
828    #[inline]
829    #[stable(feature = "rust1", since = "1.0.0")]
830    #[rustc_const_unstable(feature = "const_convert", issue = "143773")]
831    pub const fn new<S: [const] AsRef<OsStr> + ?Sized>(s: &S) -> &OsStr {
832        s.as_ref()
833    }
834
835    /// Converts a slice of bytes to an OS string slice without checking that the string contains
836    /// valid `OsStr`-encoded data.
837    ///
838    /// The byte encoding is an unspecified, platform-specific, self-synchronizing superset of UTF-8.
839    /// By being a self-synchronizing superset of UTF-8, this encoding is also a superset of 7-bit
840    /// ASCII.
841    ///
842    /// See the [module's toplevel documentation about conversions][conversions] for safe,
843    /// cross-platform [conversions] from/to native representations.
844    ///
845    /// # Safety
846    ///
847    /// As the encoding is unspecified, callers must pass in bytes that originated as a mixture of
848    /// validated UTF-8 and bytes from [`OsStr::as_encoded_bytes`] from within the same Rust version
849    /// built for the same target platform.  For example, reconstructing an `OsStr` from bytes sent
850    /// over the network or stored in a file will likely violate these safety rules.
851    ///
852    /// Due to the encoding being self-synchronizing, the bytes from [`OsStr::as_encoded_bytes`] can be
853    /// split either immediately before or immediately after any valid non-empty UTF-8 substring.
854    ///
855    /// # Example
856    ///
857    /// ```
858    /// use std::ffi::OsStr;
859    ///
860    /// let os_str = OsStr::new("Mary had a little lamb");
861    /// let bytes = os_str.as_encoded_bytes();
862    /// let words = bytes.split(|b| *b == b' ');
863    /// let words: Vec<&OsStr> = words.map(|word| {
864    ///     // SAFETY:
865    ///     // - Each `word` only contains content that originated from `OsStr::as_encoded_bytes`
866    ///     // - Only split with ASCII whitespace which is a non-empty UTF-8 substring
867    ///     unsafe { OsStr::from_encoded_bytes_unchecked(word) }
868    /// }).collect();
869    /// ```
870    ///
871    /// [conversions]: super#conversions
872    #[inline]
873    #[stable(feature = "os_str_bytes", since = "1.74.0")]
874    pub unsafe fn from_encoded_bytes_unchecked(bytes: &[u8]) -> &Self {
875        Self::from_inner(unsafe { Slice::from_encoded_bytes_unchecked(bytes) })
876    }
877
878    #[inline]
879    #[rustc_const_unstable(feature = "const_convert", issue = "143773")]
880    const fn from_inner(inner: &Slice) -> &OsStr {
881        // SAFETY: OsStr is just a wrapper of Slice,
882        // therefore converting &Slice to &OsStr is safe.
883        unsafe { &*(inner as *const Slice as *const OsStr) }
884    }
885
886    #[inline]
887    #[rustc_const_unstable(feature = "const_convert", issue = "143773")]
888    const fn from_inner_mut(inner: &mut Slice) -> &mut OsStr {
889        // SAFETY: OsStr is just a wrapper of Slice,
890        // therefore converting &mut Slice to &mut OsStr is safe.
891        // Any method that mutates OsStr must be careful not to
892        // break platform-specific encoding, in particular Wtf8 on Windows.
893        unsafe { &mut *(inner as *mut Slice as *mut OsStr) }
894    }
895
896    /// Yields a <code>&[str]</code> slice if the `OsStr` is valid Unicode.
897    ///
898    /// This conversion may entail doing a check for UTF-8 validity.
899    ///
900    /// # Examples
901    ///
902    /// ```
903    /// use std::ffi::OsStr;
904    ///
905    /// let os_str = OsStr::new("foo");
906    /// assert_eq!(os_str.to_str(), Some("foo"));
907    /// ```
908    #[stable(feature = "rust1", since = "1.0.0")]
909    #[must_use = "this returns the result of the operation, \
910                  without modifying the original"]
911    #[inline]
912    pub fn to_str(&self) -> Option<&str> {
913        self.inner.to_str().ok()
914    }
915
916    /// Converts an `OsStr` to a <code>[Cow]<[str]></code>.
917    ///
918    /// Any non-UTF-8 sequences are replaced with
919    /// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD].
920    ///
921    /// [U+FFFD]: char::REPLACEMENT_CHARACTER
922    ///
923    /// # Examples
924    ///
925    /// Calling `to_string_lossy` on an `OsStr` with invalid unicode:
926    ///
927    /// ```
928    /// // Note, due to differences in how Unix and Windows represent strings,
929    /// // we are forced to complicate this example, setting up example `OsStr`s
930    /// // with different source data and via different platform extensions.
931    /// // Understand that in reality you could end up with such example invalid
932    /// // sequences simply through collecting user command line arguments, for
933    /// // example.
934    ///
935    /// #[cfg(unix)] {
936    ///     use std::ffi::OsStr;
937    ///     use std::os::unix::ffi::OsStrExt;
938    ///
939    ///     // Here, the values 0x66 and 0x6f correspond to 'f' and 'o'
940    ///     // respectively. The value 0x80 is a lone continuation byte, invalid
941    ///     // in a UTF-8 sequence.
942    ///     let source = [0x66, 0x6f, 0x80, 0x6f];
943    ///     let os_str = OsStr::from_bytes(&source[..]);
944    ///
945    ///     assert_eq!(os_str.to_string_lossy(), "fo�o");
946    /// }
947    /// #[cfg(windows)] {
948    ///     use std::ffi::OsString;
949    ///     use std::os::windows::prelude::*;
950    ///
951    ///     // Here the values 0x0066 and 0x006f correspond to 'f' and 'o'
952    ///     // respectively. The value 0xD800 is a lone surrogate half, invalid
953    ///     // in a UTF-16 sequence.
954    ///     let source = [0x0066, 0x006f, 0xD800, 0x006f];
955    ///     let os_string = OsString::from_wide(&source[..]);
956    ///     let os_str = os_string.as_os_str();
957    ///
958    ///     assert_eq!(os_str.to_string_lossy(), "fo�o");
959    /// }
960    /// ```
961    #[stable(feature = "rust1", since = "1.0.0")]
962    #[must_use = "this returns the result of the operation, \
963                  without modifying the original"]
964    #[inline]
965    pub fn to_string_lossy(&self) -> Cow<'_, str> {
966        self.inner.to_string_lossy()
967    }
968
969    /// Copies the slice into an owned [`OsString`].
970    ///
971    /// # Examples
972    ///
973    /// ```
974    /// use std::ffi::{OsStr, OsString};
975    ///
976    /// let os_str = OsStr::new("foo");
977    /// let os_string = os_str.to_os_string();
978    /// assert_eq!(os_string, OsString::from("foo"));
979    /// ```
980    #[stable(feature = "rust1", since = "1.0.0")]
981    #[must_use = "this returns the result of the operation, \
982                  without modifying the original"]
983    #[inline]
984    #[cfg_attr(not(test), rustc_diagnostic_item = "os_str_to_os_string")]
985    pub fn to_os_string(&self) -> OsString {
986        OsString { inner: self.inner.to_owned() }
987    }
988
989    /// Checks whether the `OsStr` is empty.
990    ///
991    /// # Examples
992    ///
993    /// ```
994    /// use std::ffi::OsStr;
995    ///
996    /// let os_str = OsStr::new("");
997    /// assert!(os_str.is_empty());
998    ///
999    /// let os_str = OsStr::new("foo");
1000    /// assert!(!os_str.is_empty());
1001    /// ```
1002    #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
1003    #[must_use]
1004    #[inline]
1005    pub fn is_empty(&self) -> bool {
1006        self.inner.inner.is_empty()
1007    }
1008
1009    /// Returns the length of this `OsStr`.
1010    ///
1011    /// Note that this does **not** return the number of bytes in the string in
1012    /// OS string form.
1013    ///
1014    /// The length returned is that of the underlying storage used by `OsStr`.
1015    /// As discussed in the [`OsString`] introduction, [`OsString`] and `OsStr`
1016    /// store strings in a form best suited for cheap inter-conversion between
1017    /// native-platform and Rust string forms, which may differ significantly
1018    /// from both of them, including in storage size and encoding.
1019    ///
1020    /// This number is simply useful for passing to other methods, like
1021    /// [`OsString::with_capacity`] to avoid reallocations.
1022    ///
1023    /// See the main `OsString` documentation information about encoding and capacity units.
1024    ///
1025    /// # Examples
1026    ///
1027    /// ```
1028    /// use std::ffi::OsStr;
1029    ///
1030    /// let os_str = OsStr::new("");
1031    /// assert_eq!(os_str.len(), 0);
1032    ///
1033    /// let os_str = OsStr::new("foo");
1034    /// assert_eq!(os_str.len(), 3);
1035    /// ```
1036    #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
1037    #[must_use]
1038    #[inline]
1039    pub fn len(&self) -> usize {
1040        self.inner.inner.len()
1041    }
1042
1043    /// Converts a <code>[Box]<[OsStr]></code> into an [`OsString`] without copying or allocating.
1044    #[stable(feature = "into_boxed_os_str", since = "1.20.0")]
1045    #[must_use = "`self` will be dropped if the result is not used"]
1046    pub fn into_os_string(self: Box<Self>) -> OsString {
1047        let boxed = unsafe { Box::from_raw(Box::into_raw(self) as *mut Slice) };
1048        OsString { inner: Buf::from_box(boxed) }
1049    }
1050
1051    /// Divides one string slice into two at an index.
1052    ///
1053    /// The two slices returned go from the start of the string slice to `mid`, and from `mid` to the end of the string slice.
1054    ///
1055    /// The argument, `mid`, should be a byte offset from the start of the string.
1056    /// It must also be on a valid `OsStr` boundary.
1057    /// See [`split_at_checked`][Self::split_at_checked] for the definition of a valid boundary.
1058    ///
1059    /// Panics
1060    ///
1061    /// 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.
1062    /// For a non-panicking alternative see [`split_at_checked`][Self::split_at_checked].
1063    #[unstable(feature = "os_str_split_at", issue = "none")]
1064    pub fn split_at(&self, mid: usize) -> (&OsStr, &OsStr) {
1065        self.inner.check_public_boundary(mid);
1066
1067        // SAFETY: we've checked it's in bounds and a valid boundary
1068        unsafe { self.split_at_unchecked(mid) }
1069    }
1070
1071    /// Divides one string slice into two at an index.
1072    ///
1073    /// The two slices returned go from the start of the string slice to `mid`, and from `mid` to the end of the string slice.
1074    ///
1075    /// The argument, `mid`, should be a valid byte offset from the start of the string.
1076    /// It must also be on a valid `OsStr` boundary.
1077    /// The method returns `None` if that’s not the case.
1078    /// A valid `OsStr` boundary is one of:
1079    /// - The start of the string
1080    /// - The end of the string
1081    /// - The start of a valid non-empty UTF-8 substring
1082    /// - Immediately follows a valid non-empty UTF-8 substring
1083    #[unstable(feature = "os_str_split_at", issue = "none")]
1084    pub fn split_at_checked(&self, mid: usize) -> Option<(&OsStr, &OsStr)> {
1085        self.inner.try_check_public_boundary(mid)?;
1086
1087        // SAFETY: we've checked it's in bounds and a valid boundary
1088        unsafe { Some(self.split_at_unchecked(mid)) }
1089    }
1090
1091    /// Splits an `OsStr` without checking if `mid` is a valid boundary.
1092    /// You should use `split_at` or `split_at_checked` instead.
1093    ///
1094    /// # Safety
1095    ///
1096    /// Any caller must ensure `mid` is within bounds and lies on
1097    /// a valid `OsStr` boundary for the platform.
1098    unsafe fn split_at_unchecked(&self, mid: usize) -> (&OsStr, &OsStr) {
1099        // SAFETY: it's up to the caller to ensure this is safe.
1100        unsafe {
1101            let (first, second) = self.as_encoded_bytes().split_at_unchecked(mid);
1102            (Self::from_encoded_bytes_unchecked(first), Self::from_encoded_bytes_unchecked(second))
1103        }
1104    }
1105
1106    /// Converts an OS string slice to a byte slice.  To convert the byte slice back into an OS
1107    /// string slice, use the [`OsStr::from_encoded_bytes_unchecked`] function.
1108    ///
1109    /// The byte encoding is an unspecified, platform-specific, self-synchronizing superset of UTF-8.
1110    /// By being a self-synchronizing superset of UTF-8, this encoding is also a superset of 7-bit
1111    /// ASCII.
1112    ///
1113    /// Note: As the encoding is unspecified, any sub-slice of bytes that is not valid UTF-8 should
1114    /// be treated as opaque and only comparable within the same Rust version built for the same
1115    /// target platform.  For example, sending the slice over the network or storing it in a file
1116    /// will likely result in incompatible byte slices.  See [`OsString`] for more encoding details
1117    /// and [`std::ffi`] for platform-specific, specified conversions.
1118    ///
1119    /// [`std::ffi`]: crate::ffi
1120    #[inline]
1121    #[stable(feature = "os_str_bytes", since = "1.74.0")]
1122    pub fn as_encoded_bytes(&self) -> &[u8] {
1123        self.inner.as_encoded_bytes()
1124    }
1125
1126    /// Takes a substring based on a range that corresponds to the return value of
1127    /// [`OsStr::as_encoded_bytes`].
1128    ///
1129    /// The range's start and end must lie on valid `OsStr` boundaries.
1130    /// A valid `OsStr` boundary is one of:
1131    /// - The start of the string
1132    /// - The end of the string
1133    /// - Immediately before a valid non-empty UTF-8 substring
1134    /// - Immediately after a valid non-empty UTF-8 substring
1135    ///
1136    /// # Panics
1137    ///
1138    /// Panics if `range` does not lie on valid `OsStr` boundaries or if it
1139    /// exceeds the end of the string.
1140    ///
1141    /// # Example
1142    ///
1143    /// ```
1144    /// #![feature(os_str_slice)]
1145    ///
1146    /// use std::ffi::OsStr;
1147    ///
1148    /// let os_str = OsStr::new("foo=bar");
1149    /// let bytes = os_str.as_encoded_bytes();
1150    /// if let Some(index) = bytes.iter().position(|b| *b == b'=') {
1151    ///     let key = os_str.slice_encoded_bytes(..index);
1152    ///     let value = os_str.slice_encoded_bytes(index + 1..);
1153    ///     assert_eq!(key, "foo");
1154    ///     assert_eq!(value, "bar");
1155    /// }
1156    /// ```
1157    #[unstable(feature = "os_str_slice", issue = "118485")]
1158    pub fn slice_encoded_bytes<R: ops::RangeBounds<usize>>(&self, range: R) -> &Self {
1159        let encoded_bytes = self.as_encoded_bytes();
1160        let Range { start, end } = slice::range(range, ..encoded_bytes.len());
1161
1162        // `check_public_boundary` should panic if the index does not lie on an
1163        // `OsStr` boundary as described above. It's possible to do this in an
1164        // encoding-agnostic way, but details of the internal encoding might
1165        // permit a more efficient implementation.
1166        self.inner.check_public_boundary(start);
1167        self.inner.check_public_boundary(end);
1168
1169        // SAFETY: `slice::range` ensures that `start` and `end` are valid
1170        let slice = unsafe { encoded_bytes.get_unchecked(start..end) };
1171
1172        // SAFETY: `slice` comes from `self` and we validated the boundaries
1173        unsafe { Self::from_encoded_bytes_unchecked(slice) }
1174    }
1175
1176    /// Converts this string to its ASCII lower case equivalent in-place.
1177    ///
1178    /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
1179    /// but non-ASCII letters are unchanged.
1180    ///
1181    /// To return a new lowercased value without modifying the existing one, use
1182    /// [`OsStr::to_ascii_lowercase`].
1183    ///
1184    /// # Examples
1185    ///
1186    /// ```
1187    /// use std::ffi::OsString;
1188    ///
1189    /// let mut s = OsString::from("GRÜßE, JÜRGEN ❤");
1190    ///
1191    /// s.make_ascii_lowercase();
1192    ///
1193    /// assert_eq!("grÜße, jÜrgen ❤", s);
1194    /// ```
1195    #[stable(feature = "osstring_ascii", since = "1.53.0")]
1196    #[inline]
1197    pub fn make_ascii_lowercase(&mut self) {
1198        self.inner.make_ascii_lowercase()
1199    }
1200
1201    /// Converts this string to its ASCII upper case equivalent in-place.
1202    ///
1203    /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
1204    /// but non-ASCII letters are unchanged.
1205    ///
1206    /// To return a new uppercased value without modifying the existing one, use
1207    /// [`OsStr::to_ascii_uppercase`].
1208    ///
1209    /// # Examples
1210    ///
1211    /// ```
1212    /// use std::ffi::OsString;
1213    ///
1214    /// let mut s = OsString::from("Grüße, Jürgen ❤");
1215    ///
1216    /// s.make_ascii_uppercase();
1217    ///
1218    /// assert_eq!("GRüßE, JüRGEN ❤", s);
1219    /// ```
1220    #[stable(feature = "osstring_ascii", since = "1.53.0")]
1221    #[inline]
1222    pub fn make_ascii_uppercase(&mut self) {
1223        self.inner.make_ascii_uppercase()
1224    }
1225
1226    /// Returns a copy of this string where each character is mapped to its
1227    /// ASCII lower case equivalent.
1228    ///
1229    /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
1230    /// but non-ASCII letters are unchanged.
1231    ///
1232    /// To lowercase the value in-place, use [`OsStr::make_ascii_lowercase`].
1233    ///
1234    /// # Examples
1235    ///
1236    /// ```
1237    /// use std::ffi::OsString;
1238    /// let s = OsString::from("Grüße, Jürgen ❤");
1239    ///
1240    /// assert_eq!("grüße, jürgen ❤", s.to_ascii_lowercase());
1241    /// ```
1242    #[must_use = "to lowercase the value in-place, use `make_ascii_lowercase`"]
1243    #[stable(feature = "osstring_ascii", since = "1.53.0")]
1244    pub fn to_ascii_lowercase(&self) -> OsString {
1245        OsString::from_inner(self.inner.to_ascii_lowercase())
1246    }
1247
1248    /// Returns a copy of this string where each character is mapped to its
1249    /// ASCII upper case equivalent.
1250    ///
1251    /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
1252    /// but non-ASCII letters are unchanged.
1253    ///
1254    /// To uppercase the value in-place, use [`OsStr::make_ascii_uppercase`].
1255    ///
1256    /// # Examples
1257    ///
1258    /// ```
1259    /// use std::ffi::OsString;
1260    /// let s = OsString::from("Grüße, Jürgen ❤");
1261    ///
1262    /// assert_eq!("GRüßE, JüRGEN ❤", s.to_ascii_uppercase());
1263    /// ```
1264    #[must_use = "to uppercase the value in-place, use `make_ascii_uppercase`"]
1265    #[stable(feature = "osstring_ascii", since = "1.53.0")]
1266    pub fn to_ascii_uppercase(&self) -> OsString {
1267        OsString::from_inner(self.inner.to_ascii_uppercase())
1268    }
1269
1270    /// Checks if all characters in this string are within the ASCII range.
1271    ///
1272    /// An empty string returns `true`.
1273    ///
1274    /// # Examples
1275    ///
1276    /// ```
1277    /// use std::ffi::OsString;
1278    ///
1279    /// let ascii = OsString::from("hello!\n");
1280    /// let non_ascii = OsString::from("Grüße, Jürgen ❤");
1281    ///
1282    /// assert!(ascii.is_ascii());
1283    /// assert!(!non_ascii.is_ascii());
1284    /// ```
1285    #[stable(feature = "osstring_ascii", since = "1.53.0")]
1286    #[must_use]
1287    #[inline]
1288    pub fn is_ascii(&self) -> bool {
1289        self.inner.is_ascii()
1290    }
1291
1292    /// Checks that two strings are an ASCII case-insensitive match.
1293    ///
1294    /// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`,
1295    /// but without allocating and copying temporaries.
1296    ///
1297    /// # Examples
1298    ///
1299    /// ```
1300    /// use std::ffi::OsString;
1301    ///
1302    /// assert!(OsString::from("Ferris").eq_ignore_ascii_case("FERRIS"));
1303    /// assert!(OsString::from("Ferrös").eq_ignore_ascii_case("FERRöS"));
1304    /// assert!(!OsString::from("Ferrös").eq_ignore_ascii_case("FERRÖS"));
1305    /// ```
1306    #[stable(feature = "osstring_ascii", since = "1.53.0")]
1307    pub fn eq_ignore_ascii_case<S: AsRef<OsStr>>(&self, other: S) -> bool {
1308        self.inner.eq_ignore_ascii_case(&other.as_ref().inner)
1309    }
1310
1311    /// Returns an object that implements [`Display`] for safely printing an
1312    /// [`OsStr`] that may contain non-Unicode data. This may perform lossy
1313    /// conversion, depending on the platform.  If you would like an
1314    /// implementation which escapes the [`OsStr`] please use [`Debug`]
1315    /// instead.
1316    ///
1317    /// [`Display`]: fmt::Display
1318    /// [`Debug`]: fmt::Debug
1319    ///
1320    /// # Examples
1321    ///
1322    /// ```
1323    /// use std::ffi::OsStr;
1324    ///
1325    /// let s = OsStr::new("Hello, world!");
1326    /// println!("{}", s.display());
1327    /// ```
1328    #[stable(feature = "os_str_display", since = "1.87.0")]
1329    #[must_use = "this does not display the `OsStr`; \
1330                  it returns an object that can be displayed"]
1331    #[inline]
1332    pub fn display(&self) -> Display<'_> {
1333        Display { os_str: self }
1334    }
1335
1336    /// Returns the same string as a string slice `&OsStr`.
1337    ///
1338    /// This method is redundant when used directly on `&OsStr`, but
1339    /// it helps dereferencing other string-like types to string slices,
1340    /// for example references to `Box<OsStr>` or `Arc<OsStr>`.
1341    #[inline]
1342    #[unstable(feature = "str_as_str", issue = "130366")]
1343    pub const fn as_os_str(&self) -> &OsStr {
1344        self
1345    }
1346}
1347
1348#[stable(feature = "box_from_os_str", since = "1.17.0")]
1349impl From<&OsStr> for Box<OsStr> {
1350    /// Copies the string into a newly allocated <code>[Box]&lt;[OsStr]&gt;</code>.
1351    #[inline]
1352    fn from(s: &OsStr) -> Box<OsStr> {
1353        Box::clone_from_ref(s)
1354    }
1355}
1356
1357#[stable(feature = "box_from_mut_slice", since = "1.84.0")]
1358impl From<&mut OsStr> for Box<OsStr> {
1359    /// Copies the string into a newly allocated <code>[Box]&lt;[OsStr]&gt;</code>.
1360    #[inline]
1361    fn from(s: &mut OsStr) -> Box<OsStr> {
1362        Self::from(&*s)
1363    }
1364}
1365
1366#[stable(feature = "box_from_cow", since = "1.45.0")]
1367impl From<Cow<'_, OsStr>> for Box<OsStr> {
1368    /// Converts a `Cow<'a, OsStr>` into a <code>[Box]&lt;[OsStr]&gt;</code>,
1369    /// by copying the contents if they are borrowed.
1370    #[inline]
1371    fn from(cow: Cow<'_, OsStr>) -> Box<OsStr> {
1372        match cow {
1373            Cow::Borrowed(s) => Box::from(s),
1374            Cow::Owned(s) => Box::from(s),
1375        }
1376    }
1377}
1378
1379#[stable(feature = "os_string_from_box", since = "1.18.0")]
1380impl From<Box<OsStr>> for OsString {
1381    /// Converts a <code>[Box]<[OsStr]></code> into an [`OsString`] without copying or
1382    /// allocating.
1383    #[inline]
1384    fn from(boxed: Box<OsStr>) -> OsString {
1385        boxed.into_os_string()
1386    }
1387}
1388
1389#[stable(feature = "box_from_os_string", since = "1.20.0")]
1390impl From<OsString> for Box<OsStr> {
1391    /// Converts an [`OsString`] into a <code>[Box]<[OsStr]></code> without copying or allocating.
1392    #[inline]
1393    fn from(s: OsString) -> Box<OsStr> {
1394        s.into_boxed_os_str()
1395    }
1396}
1397
1398#[stable(feature = "more_box_slice_clone", since = "1.29.0")]
1399impl<A: Allocator + Clone> Clone for Box<OsStr, A> {
1400    #[inline]
1401    fn clone(&self) -> Self {
1402        Box::clone_from_ref_in(&**self, Self::allocator(self).clone())
1403    }
1404}
1405
1406#[unstable(feature = "clone_to_uninit", issue = "126799")]
1407unsafe impl CloneToUninit for OsStr {
1408    #[inline]
1409    #[cfg_attr(debug_assertions, track_caller)]
1410    unsafe fn clone_to_uninit(&self, dst: *mut u8) {
1411        // SAFETY: we're just a transparent wrapper around a platform-specific Slice
1412        unsafe { self.inner.clone_to_uninit(dst) }
1413    }
1414}
1415
1416#[stable(feature = "shared_from_slice2", since = "1.24.0")]
1417impl From<OsString> for Arc<OsStr> {
1418    /// Converts an [`OsString`] into an <code>[Arc]<[OsStr]></code> by moving the [`OsString`]
1419    /// data into a new [`Arc`] buffer.
1420    #[inline]
1421    fn from(s: OsString) -> Arc<OsStr> {
1422        let arc = s.inner.into_arc();
1423        unsafe { Arc::from_raw(Arc::into_raw(arc) as *const OsStr) }
1424    }
1425}
1426
1427#[stable(feature = "shared_from_slice2", since = "1.24.0")]
1428impl From<&OsStr> for Arc<OsStr> {
1429    /// Copies the string into a newly allocated <code>[Arc]&lt;[OsStr]&gt;</code>.
1430    #[inline]
1431    fn from(s: &OsStr) -> Arc<OsStr> {
1432        let arc = s.inner.into_arc();
1433        unsafe { Arc::from_raw(Arc::into_raw(arc) as *const OsStr) }
1434    }
1435}
1436
1437#[stable(feature = "shared_from_mut_slice", since = "1.84.0")]
1438impl From<&mut OsStr> for Arc<OsStr> {
1439    /// Copies the string into a newly allocated <code>[Arc]&lt;[OsStr]&gt;</code>.
1440    #[inline]
1441    fn from(s: &mut OsStr) -> Arc<OsStr> {
1442        Arc::from(&*s)
1443    }
1444}
1445
1446#[stable(feature = "shared_from_slice2", since = "1.24.0")]
1447impl From<OsString> for Rc<OsStr> {
1448    /// Converts an [`OsString`] into an <code>[Rc]<[OsStr]></code> by moving the [`OsString`]
1449    /// data into a new [`Rc`] buffer.
1450    #[inline]
1451    fn from(s: OsString) -> Rc<OsStr> {
1452        let rc = s.inner.into_rc();
1453        unsafe { Rc::from_raw(Rc::into_raw(rc) as *const OsStr) }
1454    }
1455}
1456
1457#[stable(feature = "shared_from_slice2", since = "1.24.0")]
1458impl From<&OsStr> for Rc<OsStr> {
1459    /// Copies the string into a newly allocated <code>[Rc]&lt;[OsStr]&gt;</code>.
1460    #[inline]
1461    fn from(s: &OsStr) -> Rc<OsStr> {
1462        let rc = s.inner.into_rc();
1463        unsafe { Rc::from_raw(Rc::into_raw(rc) as *const OsStr) }
1464    }
1465}
1466
1467#[stable(feature = "shared_from_mut_slice", since = "1.84.0")]
1468impl From<&mut OsStr> for Rc<OsStr> {
1469    /// Copies the string into a newly allocated <code>[Rc]&lt;[OsStr]&gt;</code>.
1470    #[inline]
1471    fn from(s: &mut OsStr) -> Rc<OsStr> {
1472        Rc::from(&*s)
1473    }
1474}
1475
1476#[stable(feature = "cow_from_osstr", since = "1.28.0")]
1477impl<'a> From<OsString> for Cow<'a, OsStr> {
1478    /// Moves the string into a [`Cow::Owned`].
1479    #[inline]
1480    fn from(s: OsString) -> Cow<'a, OsStr> {
1481        Cow::Owned(s)
1482    }
1483}
1484
1485#[stable(feature = "cow_from_osstr", since = "1.28.0")]
1486impl<'a> From<&'a OsStr> for Cow<'a, OsStr> {
1487    /// Converts the string reference into a [`Cow::Borrowed`].
1488    #[inline]
1489    fn from(s: &'a OsStr) -> Cow<'a, OsStr> {
1490        Cow::Borrowed(s)
1491    }
1492}
1493
1494#[stable(feature = "cow_from_osstr", since = "1.28.0")]
1495impl<'a> From<&'a OsString> for Cow<'a, OsStr> {
1496    /// Converts the string reference into a [`Cow::Borrowed`].
1497    #[inline]
1498    fn from(s: &'a OsString) -> Cow<'a, OsStr> {
1499        Cow::Borrowed(s.as_os_str())
1500    }
1501}
1502
1503#[stable(feature = "osstring_from_cow_osstr", since = "1.28.0")]
1504impl<'a> From<Cow<'a, OsStr>> for OsString {
1505    /// Converts a `Cow<'a, OsStr>` into an [`OsString`],
1506    /// by copying the contents if they are borrowed.
1507    #[inline]
1508    fn from(s: Cow<'a, OsStr>) -> Self {
1509        s.into_owned()
1510    }
1511}
1512
1513#[stable(feature = "str_tryfrom_osstr_impl", since = "1.72.0")]
1514impl<'a> TryFrom<&'a OsStr> for &'a str {
1515    type Error = crate::str::Utf8Error;
1516
1517    /// Tries to convert an `&OsStr` to a `&str`.
1518    ///
1519    /// ```
1520    /// use std::ffi::OsStr;
1521    ///
1522    /// let os_str = OsStr::new("foo");
1523    /// let as_str = <&str>::try_from(os_str).unwrap();
1524    /// assert_eq!(as_str, "foo");
1525    /// ```
1526    fn try_from(value: &'a OsStr) -> Result<Self, Self::Error> {
1527        value.inner.to_str()
1528    }
1529}
1530
1531#[stable(feature = "box_default_extra", since = "1.17.0")]
1532impl Default for Box<OsStr> {
1533    #[inline]
1534    fn default() -> Box<OsStr> {
1535        let rw = Box::into_raw(Slice::empty_box()) as *mut OsStr;
1536        unsafe { Box::from_raw(rw) }
1537    }
1538}
1539
1540#[stable(feature = "osstring_default", since = "1.9.0")]
1541impl Default for &OsStr {
1542    /// Creates an empty `OsStr`.
1543    #[inline]
1544    fn default() -> Self {
1545        OsStr::new("")
1546    }
1547}
1548
1549#[stable(feature = "rust1", since = "1.0.0")]
1550impl PartialEq for OsStr {
1551    #[inline]
1552    fn eq(&self, other: &OsStr) -> bool {
1553        self.as_encoded_bytes().eq(other.as_encoded_bytes())
1554    }
1555}
1556
1557#[stable(feature = "rust1", since = "1.0.0")]
1558impl PartialEq<str> for OsStr {
1559    #[inline]
1560    fn eq(&self, other: &str) -> bool {
1561        *self == *OsStr::new(other)
1562    }
1563}
1564
1565#[stable(feature = "rust1", since = "1.0.0")]
1566impl PartialEq<OsStr> for str {
1567    #[inline]
1568    fn eq(&self, other: &OsStr) -> bool {
1569        *other == *OsStr::new(self)
1570    }
1571}
1572
1573#[stable(feature = "rust1", since = "1.0.0")]
1574impl Eq for OsStr {}
1575
1576#[stable(feature = "rust1", since = "1.0.0")]
1577impl PartialOrd for OsStr {
1578    #[inline]
1579    fn partial_cmp(&self, other: &OsStr) -> Option<cmp::Ordering> {
1580        self.as_encoded_bytes().partial_cmp(other.as_encoded_bytes())
1581    }
1582    #[inline]
1583    fn lt(&self, other: &OsStr) -> bool {
1584        self.as_encoded_bytes().lt(other.as_encoded_bytes())
1585    }
1586    #[inline]
1587    fn le(&self, other: &OsStr) -> bool {
1588        self.as_encoded_bytes().le(other.as_encoded_bytes())
1589    }
1590    #[inline]
1591    fn gt(&self, other: &OsStr) -> bool {
1592        self.as_encoded_bytes().gt(other.as_encoded_bytes())
1593    }
1594    #[inline]
1595    fn ge(&self, other: &OsStr) -> bool {
1596        self.as_encoded_bytes().ge(other.as_encoded_bytes())
1597    }
1598}
1599
1600#[stable(feature = "rust1", since = "1.0.0")]
1601impl PartialOrd<str> for OsStr {
1602    #[inline]
1603    fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
1604        self.partial_cmp(OsStr::new(other))
1605    }
1606}
1607
1608// FIXME (#19470): cannot provide PartialOrd<OsStr> for str until we
1609// have more flexible coherence rules.
1610
1611#[stable(feature = "rust1", since = "1.0.0")]
1612impl Ord for OsStr {
1613    #[inline]
1614    fn cmp(&self, other: &OsStr) -> cmp::Ordering {
1615        self.as_encoded_bytes().cmp(other.as_encoded_bytes())
1616    }
1617}
1618
1619macro_rules! impl_cmp {
1620    ($lhs:ty, $rhs: ty) => {
1621        #[stable(feature = "cmp_os_str", since = "1.8.0")]
1622        impl PartialEq<$rhs> for $lhs {
1623            #[inline]
1624            fn eq(&self, other: &$rhs) -> bool {
1625                <OsStr as PartialEq>::eq(self, other)
1626            }
1627        }
1628
1629        #[stable(feature = "cmp_os_str", since = "1.8.0")]
1630        impl PartialEq<$lhs> for $rhs {
1631            #[inline]
1632            fn eq(&self, other: &$lhs) -> bool {
1633                <OsStr as PartialEq>::eq(self, other)
1634            }
1635        }
1636
1637        #[stable(feature = "cmp_os_str", since = "1.8.0")]
1638        impl PartialOrd<$rhs> for $lhs {
1639            #[inline]
1640            fn partial_cmp(&self, other: &$rhs) -> Option<cmp::Ordering> {
1641                <OsStr as PartialOrd>::partial_cmp(self, other)
1642            }
1643        }
1644
1645        #[stable(feature = "cmp_os_str", since = "1.8.0")]
1646        impl PartialOrd<$lhs> for $rhs {
1647            #[inline]
1648            fn partial_cmp(&self, other: &$lhs) -> Option<cmp::Ordering> {
1649                <OsStr as PartialOrd>::partial_cmp(self, other)
1650            }
1651        }
1652    };
1653}
1654
1655impl_cmp!(OsString, OsStr);
1656impl_cmp!(OsString, &OsStr);
1657impl_cmp!(Cow<'_, OsStr>, OsStr);
1658impl_cmp!(Cow<'_, OsStr>, &OsStr);
1659impl_cmp!(Cow<'_, OsStr>, OsString);
1660
1661#[stable(feature = "rust1", since = "1.0.0")]
1662impl Hash for OsStr {
1663    #[inline]
1664    fn hash<H: Hasher>(&self, state: &mut H) {
1665        self.as_encoded_bytes().hash(state)
1666    }
1667}
1668
1669#[stable(feature = "rust1", since = "1.0.0")]
1670impl fmt::Debug for OsStr {
1671    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1672        fmt::Debug::fmt(&self.inner, formatter)
1673    }
1674}
1675
1676/// Helper struct for safely printing an [`OsStr`] with [`format!`] and `{}`.
1677///
1678/// An [`OsStr`] might contain non-Unicode data. This `struct` implements the
1679/// [`Display`] trait in a way that mitigates that. It is created by the
1680/// [`display`](OsStr::display) method on [`OsStr`]. This may perform lossy
1681/// conversion, depending on the platform. If you would like an implementation
1682/// which escapes the [`OsStr`] please use [`Debug`] instead.
1683///
1684/// # Examples
1685///
1686/// ```
1687/// use std::ffi::OsStr;
1688///
1689/// let s = OsStr::new("Hello, world!");
1690/// println!("{}", s.display());
1691/// ```
1692///
1693/// [`Display`]: fmt::Display
1694/// [`format!`]: crate::format
1695#[stable(feature = "os_str_display", since = "1.87.0")]
1696pub struct Display<'a> {
1697    os_str: &'a OsStr,
1698}
1699
1700#[stable(feature = "os_str_display", since = "1.87.0")]
1701impl fmt::Debug for Display<'_> {
1702    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1703        fmt::Debug::fmt(&self.os_str, f)
1704    }
1705}
1706
1707#[stable(feature = "os_str_display", since = "1.87.0")]
1708impl fmt::Display for Display<'_> {
1709    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1710        fmt::Display::fmt(&self.os_str.inner, f)
1711    }
1712}
1713
1714#[unstable(feature = "slice_concat_ext", issue = "27747")]
1715impl<S: Borrow<OsStr>> alloc::slice::Join<&OsStr> for [S] {
1716    type Output = OsString;
1717
1718    fn join(slice: &Self, sep: &OsStr) -> OsString {
1719        let Some((first, suffix)) = slice.split_first() else {
1720            return OsString::new();
1721        };
1722        let first_owned = first.borrow().to_owned();
1723        suffix.iter().fold(first_owned, |mut a, b| {
1724            a.push(sep);
1725            a.push(b.borrow());
1726            a
1727        })
1728    }
1729}
1730
1731#[stable(feature = "rust1", since = "1.0.0")]
1732impl Borrow<OsStr> for OsString {
1733    #[inline]
1734    fn borrow(&self) -> &OsStr {
1735        &self[..]
1736    }
1737}
1738
1739#[stable(feature = "rust1", since = "1.0.0")]
1740impl ToOwned for OsStr {
1741    type Owned = OsString;
1742    #[inline]
1743    fn to_owned(&self) -> OsString {
1744        self.to_os_string()
1745    }
1746    #[inline]
1747    fn clone_into(&self, target: &mut OsString) {
1748        self.inner.clone_into(&mut target.inner)
1749    }
1750}
1751
1752#[stable(feature = "rust1", since = "1.0.0")]
1753#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
1754const impl AsRef<OsStr> for OsStr {
1755    #[inline]
1756    fn as_ref(&self) -> &OsStr {
1757        self
1758    }
1759}
1760
1761#[stable(feature = "rust1", since = "1.0.0")]
1762impl AsRef<OsStr> for OsString {
1763    #[inline]
1764    fn as_ref(&self) -> &OsStr {
1765        self
1766    }
1767}
1768
1769#[stable(feature = "rust1", since = "1.0.0")]
1770impl AsRef<OsStr> for str {
1771    #[inline]
1772    fn as_ref(&self) -> &OsStr {
1773        OsStr::from_inner(Slice::from_str(self))
1774    }
1775}
1776
1777#[stable(feature = "rust1", since = "1.0.0")]
1778impl AsRef<OsStr> for String {
1779    #[inline]
1780    fn as_ref(&self) -> &OsStr {
1781        (**self).as_ref()
1782    }
1783}
1784
1785impl FromInner<Buf> for OsString {
1786    #[inline]
1787    fn from_inner(buf: Buf) -> OsString {
1788        OsString { inner: buf }
1789    }
1790}
1791
1792impl IntoInner<Buf> for OsString {
1793    #[inline]
1794    fn into_inner(self) -> Buf {
1795        self.inner
1796    }
1797}
1798
1799impl AsInner<Slice> for OsStr {
1800    #[inline]
1801    fn as_inner(&self) -> &Slice {
1802        &self.inner
1803    }
1804}
1805
1806#[stable(feature = "osstring_from_str", since = "1.45.0")]
1807impl FromStr for OsString {
1808    type Err = !;
1809
1810    #[inline]
1811    fn from_str(s: &str) -> Result<Self, !> {
1812        Ok(OsString::from(s))
1813    }
1814}
1815
1816#[stable(feature = "osstring_extend", since = "1.52.0")]
1817impl Extend<OsString> for OsString {
1818    #[inline]
1819    fn extend<I: IntoIterator<Item = OsString>>(&mut self, iter: I) {
1820        for s in iter {
1821            self.push(&s);
1822        }
1823    }
1824}
1825
1826#[stable(feature = "osstring_extend", since = "1.52.0")]
1827impl<'a> Extend<&'a OsStr> for OsString {
1828    #[inline]
1829    fn extend<I: IntoIterator<Item = &'a OsStr>>(&mut self, iter: I) {
1830        for s in iter {
1831            self.push(s);
1832        }
1833    }
1834}
1835
1836#[stable(feature = "osstring_extend", since = "1.52.0")]
1837impl<'a> Extend<Cow<'a, OsStr>> for OsString {
1838    #[inline]
1839    fn extend<I: IntoIterator<Item = Cow<'a, OsStr>>>(&mut self, iter: I) {
1840        for s in iter {
1841            self.push(&s);
1842        }
1843    }
1844}
1845
1846#[stable(feature = "osstring_extend", since = "1.52.0")]
1847impl FromIterator<OsString> for OsString {
1848    #[inline]
1849    fn from_iter<I: IntoIterator<Item = OsString>>(iter: I) -> Self {
1850        let mut iterator = iter.into_iter();
1851
1852        // Because we're iterating over `OsString`s, we can avoid at least
1853        // one allocation by getting the first string from the iterator
1854        // and appending to it all the subsequent strings.
1855        match iterator.next() {
1856            None => OsString::new(),
1857            Some(mut buf) => {
1858                buf.extend(iterator);
1859                buf
1860            }
1861        }
1862    }
1863}
1864
1865#[stable(feature = "osstring_extend", since = "1.52.0")]
1866impl<'a> FromIterator<&'a OsStr> for OsString {
1867    #[inline]
1868    fn from_iter<I: IntoIterator<Item = &'a OsStr>>(iter: I) -> Self {
1869        let mut buf = Self::new();
1870        for s in iter {
1871            buf.push(s);
1872        }
1873        buf
1874    }
1875}
1876
1877#[stable(feature = "osstring_extend", since = "1.52.0")]
1878impl<'a> FromIterator<Cow<'a, OsStr>> for OsString {
1879    #[inline]
1880    fn from_iter<I: IntoIterator<Item = Cow<'a, OsStr>>>(iter: I) -> Self {
1881        let mut iterator = iter.into_iter();
1882
1883        // Because we're iterating over `OsString`s, we can avoid at least
1884        // one allocation by getting the first owned string from the iterator
1885        // and appending to it all the subsequent strings.
1886        match iterator.next() {
1887            None => OsString::new(),
1888            Some(Cow::Owned(mut buf)) => {
1889                buf.extend(iterator);
1890                buf
1891            }
1892            Some(Cow::Borrowed(buf)) => {
1893                let mut buf = OsString::from(buf);
1894                buf.extend(iterator);
1895                buf
1896            }
1897        }
1898    }
1899}