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