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