std/ffi/
os_str.rs

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

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy