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