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