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