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