]> git.proxmox.com Git - rustc.git/blob - library/std/src/ffi/os_str.rs
New upstream version 1.55.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::fmt;
7 use crate::hash::{Hash, Hasher};
8 use crate::iter::{Extend, FromIterator};
9 use crate::ops;
10 use crate::rc::Rc;
11 use crate::str::FromStr;
12 use crate::sync::Arc;
13
14 use crate::sys::os_str::{Buf, Slice};
15 use crate::sys_common::{AsInner, FromInner, IntoInner};
16
17 /// A type that can represent owned, mutable platform-native strings, but is
18 /// cheaply inter-convertible with Rust strings.
19 ///
20 /// The need for this type arises from the fact that:
21 ///
22 /// * On Unix systems, strings are often arbitrary sequences of non-zero
23 /// bytes, in many cases interpreted as UTF-8.
24 ///
25 /// * On Windows, strings are often arbitrary sequences of non-zero 16-bit
26 /// values, interpreted as UTF-16 when it is valid to do so.
27 ///
28 /// * In Rust, strings are always valid UTF-8, which may contain zeros.
29 ///
30 /// `OsString` and [`OsStr`] bridge this gap by simultaneously representing Rust
31 /// and platform-native string values, and in particular allowing a Rust string
32 /// to be converted into an "OS" string with no cost if possible. A consequence
33 /// of this is that `OsString` instances are *not* `NUL` terminated; in order
34 /// to pass to e.g., Unix system call, you should create a [`CStr`].
35 ///
36 /// `OsString` is to [`&OsStr`] as [`String`] is to [`&str`]: the former
37 /// in each pair are owned strings; the latter are borrowed
38 /// references.
39 ///
40 /// Note, `OsString` and [`OsStr`] internally do not necessarily hold strings in
41 /// the form native to the platform; While on Unix, strings are stored as a
42 /// sequence of 8-bit values, on Windows, where strings are 16-bit value based
43 /// as just discussed, strings are also actually stored as a sequence of 8-bit
44 /// values, encoded in a less-strict variant of UTF-8. This is useful to
45 /// understand when handling capacity and length values.
46 ///
47 /// # Creating an `OsString`
48 ///
49 /// **From a Rust string**: `OsString` implements
50 /// [`From`]`<`[`String`]`>`, so you can use `my_string.from` to
51 /// create an `OsString` from a normal Rust string.
52 ///
53 /// **From slices:** Just like you can start with an empty Rust
54 /// [`String`] and then [`String::push_str`] `&str`
55 /// sub-string slices into it, you can create an empty `OsString` with
56 /// the [`OsString::new`] method and then push string slices into it with the
57 /// [`OsString::push`] method.
58 ///
59 /// # Extracting a borrowed reference to the whole OS string
60 ///
61 /// You can use the [`OsString::as_os_str`] method to get an `&`[`OsStr`] from
62 /// an `OsString`; this is effectively a borrowed reference to the
63 /// whole string.
64 ///
65 /// # Conversions
66 ///
67 /// See the [module's toplevel documentation about conversions][conversions] for a discussion on
68 /// the traits which `OsString` implements for [conversions] from/to native representations.
69 ///
70 /// [`&OsStr`]: OsStr
71 /// [`&str`]: str
72 /// [`CStr`]: crate::ffi::CStr
73 /// [conversions]: super#conversions
74 #[cfg_attr(not(test), rustc_diagnostic_item = "OsString")]
75 #[stable(feature = "rust1", since = "1.0.0")]
76 pub struct OsString {
77 inner: Buf,
78 }
79
80 /// Allows extension traits within `std`.
81 #[unstable(feature = "sealed", issue = "none")]
82 impl crate::sealed::Sealed for OsString {}
83
84 /// Borrowed reference to an OS string (see [`OsString`]).
85 ///
86 /// This type represents a borrowed reference to a string in the operating system's preferred
87 /// representation.
88 ///
89 /// `&OsStr` is to [`OsString`] as [`&str`] is to [`String`]: the former in each pair are borrowed
90 /// references; the latter are owned strings.
91 ///
92 /// See the [module's toplevel documentation about conversions][conversions] for a discussion on
93 /// the traits which `OsStr` implements for [conversions] from/to native representations.
94 ///
95 /// [`&str`]: str
96 /// [conversions]: super#conversions
97 #[cfg_attr(not(test), rustc_diagnostic_item = "OsStr")]
98 #[stable(feature = "rust1", since = "1.0.0")]
99 // FIXME:
100 // `OsStr::from_inner` current implementation relies
101 // on `OsStr` being layout-compatible with `Slice`.
102 // When attribute privacy is implemented, `OsStr` should be annotated as `#[repr(transparent)]`.
103 // Anyway, `OsStr` representation and layout are considered implementation details, are
104 // not documented and must not be relied upon.
105 pub struct OsStr {
106 inner: Slice,
107 }
108
109 /// Allows extension traits within `std`.
110 #[unstable(feature = "sealed", issue = "none")]
111 impl crate::sealed::Sealed for OsStr {}
112
113 impl OsString {
114 /// Constructs a new empty `OsString`.
115 ///
116 /// # Examples
117 ///
118 /// ```
119 /// use std::ffi::OsString;
120 ///
121 /// let os_string = OsString::new();
122 /// ```
123 #[stable(feature = "rust1", since = "1.0.0")]
124 #[inline]
125 pub fn new() -> OsString {
126 OsString { inner: Buf::from_string(String::new()) }
127 }
128
129 /// Converts to an [`OsStr`] slice.
130 ///
131 /// # Examples
132 ///
133 /// ```
134 /// use std::ffi::{OsString, OsStr};
135 ///
136 /// let os_string = OsString::from("foo");
137 /// let os_str = OsStr::new("foo");
138 /// assert_eq!(os_string.as_os_str(), os_str);
139 /// ```
140 #[stable(feature = "rust1", since = "1.0.0")]
141 #[inline]
142 pub fn as_os_str(&self) -> &OsStr {
143 self
144 }
145
146 /// Converts the `OsString` into a [`String`] if it contains valid Unicode data.
147 ///
148 /// On failure, ownership of the original `OsString` is returned.
149 ///
150 /// # Examples
151 ///
152 /// ```
153 /// use std::ffi::OsString;
154 ///
155 /// let os_string = OsString::from("foo");
156 /// let string = os_string.into_string();
157 /// assert_eq!(string, Ok(String::from("foo")));
158 /// ```
159 #[stable(feature = "rust1", since = "1.0.0")]
160 #[inline]
161 pub fn into_string(self) -> Result<String, OsString> {
162 self.inner.into_string().map_err(|buf| OsString { inner: buf })
163 }
164
165 /// Extends the string with the given [`&OsStr`] slice.
166 ///
167 /// [`&OsStr`]: OsStr
168 ///
169 /// # Examples
170 ///
171 /// ```
172 /// use std::ffi::OsString;
173 ///
174 /// let mut os_string = OsString::from("foo");
175 /// os_string.push("bar");
176 /// assert_eq!(&os_string, "foobar");
177 /// ```
178 #[stable(feature = "rust1", since = "1.0.0")]
179 #[inline]
180 pub fn push<T: AsRef<OsStr>>(&mut self, s: T) {
181 self.inner.push_slice(&s.as_ref().inner)
182 }
183
184 /// Creates a new `OsString` with the given capacity.
185 ///
186 /// The string will be able to hold exactly `capacity` length units of other
187 /// OS strings without reallocating. If `capacity` is 0, the string will not
188 /// allocate.
189 ///
190 /// See main `OsString` documentation information about encoding.
191 ///
192 /// # Examples
193 ///
194 /// ```
195 /// use std::ffi::OsString;
196 ///
197 /// let mut os_string = OsString::with_capacity(10);
198 /// let capacity = os_string.capacity();
199 ///
200 /// // This push is done without reallocating
201 /// os_string.push("foo");
202 ///
203 /// assert_eq!(capacity, os_string.capacity());
204 /// ```
205 #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
206 #[inline]
207 pub fn with_capacity(capacity: usize) -> OsString {
208 OsString { inner: Buf::with_capacity(capacity) }
209 }
210
211 /// Truncates the `OsString` to zero length.
212 ///
213 /// # Examples
214 ///
215 /// ```
216 /// use std::ffi::OsString;
217 ///
218 /// let mut os_string = OsString::from("foo");
219 /// assert_eq!(&os_string, "foo");
220 ///
221 /// os_string.clear();
222 /// assert_eq!(&os_string, "");
223 /// ```
224 #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
225 #[inline]
226 pub fn clear(&mut self) {
227 self.inner.clear()
228 }
229
230 /// Returns the capacity this `OsString` can hold without reallocating.
231 ///
232 /// See `OsString` introduction for information about encoding.
233 ///
234 /// # Examples
235 ///
236 /// ```
237 /// use std::ffi::OsString;
238 ///
239 /// let os_string = OsString::with_capacity(10);
240 /// assert!(os_string.capacity() >= 10);
241 /// ```
242 #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
243 #[inline]
244 pub fn capacity(&self) -> usize {
245 self.inner.capacity()
246 }
247
248 /// Reserves capacity for at least `additional` more capacity to be inserted
249 /// in the given `OsString`.
250 ///
251 /// The collection may reserve more space to avoid frequent reallocations.
252 ///
253 /// # Examples
254 ///
255 /// ```
256 /// use std::ffi::OsString;
257 ///
258 /// let mut s = OsString::new();
259 /// s.reserve(10);
260 /// assert!(s.capacity() >= 10);
261 /// ```
262 #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
263 #[inline]
264 pub fn reserve(&mut self, additional: usize) {
265 self.inner.reserve(additional)
266 }
267
268 /// Reserves the minimum capacity for exactly `additional` more capacity to
269 /// be inserted in the given `OsString`. Does nothing if the capacity is
270 /// already sufficient.
271 ///
272 /// Note that the allocator may give the collection more space than it
273 /// requests. Therefore, capacity can not be relied upon to be precisely
274 /// minimal. Prefer reserve if future insertions are expected.
275 ///
276 /// # Examples
277 ///
278 /// ```
279 /// use std::ffi::OsString;
280 ///
281 /// let mut s = OsString::new();
282 /// s.reserve_exact(10);
283 /// assert!(s.capacity() >= 10);
284 /// ```
285 #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
286 #[inline]
287 pub fn reserve_exact(&mut self, additional: usize) {
288 self.inner.reserve_exact(additional)
289 }
290
291 /// Shrinks the capacity of the `OsString` to match its length.
292 ///
293 /// # Examples
294 ///
295 /// ```
296 /// use std::ffi::OsString;
297 ///
298 /// let mut s = OsString::from("foo");
299 ///
300 /// s.reserve(100);
301 /// assert!(s.capacity() >= 100);
302 ///
303 /// s.shrink_to_fit();
304 /// assert_eq!(3, s.capacity());
305 /// ```
306 #[stable(feature = "osstring_shrink_to_fit", since = "1.19.0")]
307 #[inline]
308 pub fn shrink_to_fit(&mut self) {
309 self.inner.shrink_to_fit()
310 }
311
312 /// Shrinks the capacity of the `OsString` with a lower bound.
313 ///
314 /// The capacity will remain at least as large as both the length
315 /// and the supplied value.
316 ///
317 /// If the current capacity is less than the lower limit, this is a no-op.
318 ///
319 /// # Examples
320 ///
321 /// ```
322 /// #![feature(shrink_to)]
323 /// use std::ffi::OsString;
324 ///
325 /// let mut s = OsString::from("foo");
326 ///
327 /// s.reserve(100);
328 /// assert!(s.capacity() >= 100);
329 ///
330 /// s.shrink_to(10);
331 /// assert!(s.capacity() >= 10);
332 /// s.shrink_to(0);
333 /// assert!(s.capacity() >= 3);
334 /// ```
335 #[inline]
336 #[unstable(feature = "shrink_to", reason = "new API", issue = "56431")]
337 pub fn shrink_to(&mut self, min_capacity: usize) {
338 self.inner.shrink_to(min_capacity)
339 }
340
341 /// Converts this `OsString` into a boxed [`OsStr`].
342 ///
343 /// # Examples
344 ///
345 /// ```
346 /// use std::ffi::{OsString, OsStr};
347 ///
348 /// let s = OsString::from("hello");
349 ///
350 /// let b: Box<OsStr> = s.into_boxed_os_str();
351 /// ```
352 #[stable(feature = "into_boxed_os_str", since = "1.20.0")]
353 pub fn into_boxed_os_str(self) -> Box<OsStr> {
354 let rw = Box::into_raw(self.inner.into_box()) as *mut OsStr;
355 unsafe { Box::from_raw(rw) }
356 }
357 }
358
359 #[stable(feature = "rust1", since = "1.0.0")]
360 impl From<String> for OsString {
361 /// Converts a [`String`] into a [`OsString`].
362 ///
363 /// This conversion does not allocate or copy memory.
364 #[inline]
365 fn from(s: String) -> OsString {
366 OsString { inner: Buf::from_string(s) }
367 }
368 }
369
370 #[stable(feature = "rust1", since = "1.0.0")]
371 impl<T: ?Sized + AsRef<OsStr>> From<&T> for OsString {
372 fn from(s: &T) -> OsString {
373 s.as_ref().to_os_string()
374 }
375 }
376
377 #[stable(feature = "rust1", since = "1.0.0")]
378 impl ops::Index<ops::RangeFull> for OsString {
379 type Output = OsStr;
380
381 #[inline]
382 fn index(&self, _index: ops::RangeFull) -> &OsStr {
383 OsStr::from_inner(self.inner.as_slice())
384 }
385 }
386
387 #[stable(feature = "mut_osstr", since = "1.44.0")]
388 impl ops::IndexMut<ops::RangeFull> for OsString {
389 #[inline]
390 fn index_mut(&mut self, _index: ops::RangeFull) -> &mut OsStr {
391 OsStr::from_inner_mut(self.inner.as_mut_slice())
392 }
393 }
394
395 #[stable(feature = "rust1", since = "1.0.0")]
396 impl ops::Deref for OsString {
397 type Target = OsStr;
398
399 #[inline]
400 fn deref(&self) -> &OsStr {
401 &self[..]
402 }
403 }
404
405 #[stable(feature = "mut_osstr", since = "1.44.0")]
406 impl ops::DerefMut for OsString {
407 #[inline]
408 fn deref_mut(&mut self) -> &mut OsStr {
409 &mut self[..]
410 }
411 }
412
413 #[stable(feature = "osstring_default", since = "1.9.0")]
414 impl Default for OsString {
415 /// Constructs an empty `OsString`.
416 #[inline]
417 fn default() -> OsString {
418 OsString::new()
419 }
420 }
421
422 #[stable(feature = "rust1", since = "1.0.0")]
423 impl Clone for OsString {
424 #[inline]
425 fn clone(&self) -> Self {
426 OsString { inner: self.inner.clone() }
427 }
428
429 #[inline]
430 fn clone_from(&mut self, source: &Self) {
431 self.inner.clone_from(&source.inner)
432 }
433 }
434
435 #[stable(feature = "rust1", since = "1.0.0")]
436 impl fmt::Debug for OsString {
437 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
438 fmt::Debug::fmt(&**self, formatter)
439 }
440 }
441
442 #[stable(feature = "rust1", since = "1.0.0")]
443 impl PartialEq for OsString {
444 #[inline]
445 fn eq(&self, other: &OsString) -> bool {
446 &**self == &**other
447 }
448 }
449
450 #[stable(feature = "rust1", since = "1.0.0")]
451 impl PartialEq<str> for OsString {
452 #[inline]
453 fn eq(&self, other: &str) -> bool {
454 &**self == other
455 }
456 }
457
458 #[stable(feature = "rust1", since = "1.0.0")]
459 impl PartialEq<OsString> for str {
460 #[inline]
461 fn eq(&self, other: &OsString) -> bool {
462 &**other == self
463 }
464 }
465
466 #[stable(feature = "os_str_str_ref_eq", since = "1.29.0")]
467 impl PartialEq<&str> for OsString {
468 #[inline]
469 fn eq(&self, other: &&str) -> bool {
470 **self == **other
471 }
472 }
473
474 #[stable(feature = "os_str_str_ref_eq", since = "1.29.0")]
475 impl<'a> PartialEq<OsString> for &'a str {
476 #[inline]
477 fn eq(&self, other: &OsString) -> bool {
478 **other == **self
479 }
480 }
481
482 #[stable(feature = "rust1", since = "1.0.0")]
483 impl Eq for OsString {}
484
485 #[stable(feature = "rust1", since = "1.0.0")]
486 impl PartialOrd for OsString {
487 #[inline]
488 fn partial_cmp(&self, other: &OsString) -> Option<cmp::Ordering> {
489 (&**self).partial_cmp(&**other)
490 }
491 #[inline]
492 fn lt(&self, other: &OsString) -> bool {
493 &**self < &**other
494 }
495 #[inline]
496 fn le(&self, other: &OsString) -> bool {
497 &**self <= &**other
498 }
499 #[inline]
500 fn gt(&self, other: &OsString) -> bool {
501 &**self > &**other
502 }
503 #[inline]
504 fn ge(&self, other: &OsString) -> bool {
505 &**self >= &**other
506 }
507 }
508
509 #[stable(feature = "rust1", since = "1.0.0")]
510 impl PartialOrd<str> for OsString {
511 #[inline]
512 fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
513 (&**self).partial_cmp(other)
514 }
515 }
516
517 #[stable(feature = "rust1", since = "1.0.0")]
518 impl Ord for OsString {
519 #[inline]
520 fn cmp(&self, other: &OsString) -> cmp::Ordering {
521 (&**self).cmp(&**other)
522 }
523 }
524
525 #[stable(feature = "rust1", since = "1.0.0")]
526 impl Hash for OsString {
527 #[inline]
528 fn hash<H: Hasher>(&self, state: &mut H) {
529 (&**self).hash(state)
530 }
531 }
532
533 impl OsStr {
534 /// Coerces into an `OsStr` slice.
535 ///
536 /// # Examples
537 ///
538 /// ```
539 /// use std::ffi::OsStr;
540 ///
541 /// let os_str = OsStr::new("foo");
542 /// ```
543 #[inline]
544 #[stable(feature = "rust1", since = "1.0.0")]
545 pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &OsStr {
546 s.as_ref()
547 }
548
549 #[inline]
550 fn from_inner(inner: &Slice) -> &OsStr {
551 // SAFETY: OsStr is just a wrapper of Slice,
552 // therefore converting &Slice to &OsStr is safe.
553 unsafe { &*(inner as *const Slice as *const OsStr) }
554 }
555
556 #[inline]
557 fn from_inner_mut(inner: &mut Slice) -> &mut OsStr {
558 // SAFETY: OsStr is just a wrapper of Slice,
559 // therefore converting &mut Slice to &mut OsStr is safe.
560 // Any method that mutates OsStr must be careful not to
561 // break platform-specific encoding, in particular Wtf8 on Windows.
562 unsafe { &mut *(inner as *mut Slice as *mut OsStr) }
563 }
564
565 /// Yields a [`&str`] slice if the `OsStr` is valid Unicode.
566 ///
567 /// This conversion may entail doing a check for UTF-8 validity.
568 ///
569 /// [`&str`]: str
570 ///
571 /// # Examples
572 ///
573 /// ```
574 /// use std::ffi::OsStr;
575 ///
576 /// let os_str = OsStr::new("foo");
577 /// assert_eq!(os_str.to_str(), Some("foo"));
578 /// ```
579 #[stable(feature = "rust1", since = "1.0.0")]
580 #[inline]
581 pub fn to_str(&self) -> Option<&str> {
582 self.inner.to_str()
583 }
584
585 /// Converts an `OsStr` to a [`Cow`]`<`[`str`]`>`.
586 ///
587 /// Any non-Unicode sequences are replaced with
588 /// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD].
589 ///
590 /// [U+FFFD]: crate::char::REPLACEMENT_CHARACTER
591 ///
592 /// # Examples
593 ///
594 /// Calling `to_string_lossy` on an `OsStr` with invalid unicode:
595 ///
596 /// ```
597 /// // Note, due to differences in how Unix and Windows represent strings,
598 /// // we are forced to complicate this example, setting up example `OsStr`s
599 /// // with different source data and via different platform extensions.
600 /// // Understand that in reality you could end up with such example invalid
601 /// // sequences simply through collecting user command line arguments, for
602 /// // example.
603 ///
604 /// #[cfg(unix)] {
605 /// use std::ffi::OsStr;
606 /// use std::os::unix::ffi::OsStrExt;
607 ///
608 /// // Here, the values 0x66 and 0x6f correspond to 'f' and 'o'
609 /// // respectively. The value 0x80 is a lone continuation byte, invalid
610 /// // in a UTF-8 sequence.
611 /// let source = [0x66, 0x6f, 0x80, 0x6f];
612 /// let os_str = OsStr::from_bytes(&source[..]);
613 ///
614 /// assert_eq!(os_str.to_string_lossy(), "fo�o");
615 /// }
616 /// #[cfg(windows)] {
617 /// use std::ffi::OsString;
618 /// use std::os::windows::prelude::*;
619 ///
620 /// // Here the values 0x0066 and 0x006f correspond to 'f' and 'o'
621 /// // respectively. The value 0xD800 is a lone surrogate half, invalid
622 /// // in a UTF-16 sequence.
623 /// let source = [0x0066, 0x006f, 0xD800, 0x006f];
624 /// let os_string = OsString::from_wide(&source[..]);
625 /// let os_str = os_string.as_os_str();
626 ///
627 /// assert_eq!(os_str.to_string_lossy(), "fo�o");
628 /// }
629 /// ```
630 #[stable(feature = "rust1", since = "1.0.0")]
631 #[inline]
632 pub fn to_string_lossy(&self) -> Cow<'_, str> {
633 self.inner.to_string_lossy()
634 }
635
636 /// Copies the slice into an owned [`OsString`].
637 ///
638 /// # Examples
639 ///
640 /// ```
641 /// use std::ffi::{OsStr, OsString};
642 ///
643 /// let os_str = OsStr::new("foo");
644 /// let os_string = os_str.to_os_string();
645 /// assert_eq!(os_string, OsString::from("foo"));
646 /// ```
647 #[stable(feature = "rust1", since = "1.0.0")]
648 #[inline]
649 pub fn to_os_string(&self) -> OsString {
650 OsString { inner: self.inner.to_owned() }
651 }
652
653 /// Checks whether the `OsStr` is empty.
654 ///
655 /// # Examples
656 ///
657 /// ```
658 /// use std::ffi::OsStr;
659 ///
660 /// let os_str = OsStr::new("");
661 /// assert!(os_str.is_empty());
662 ///
663 /// let os_str = OsStr::new("foo");
664 /// assert!(!os_str.is_empty());
665 /// ```
666 #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
667 #[inline]
668 pub fn is_empty(&self) -> bool {
669 self.inner.inner.is_empty()
670 }
671
672 /// Returns the length of this `OsStr`.
673 ///
674 /// Note that this does **not** return the number of bytes in the string in
675 /// OS string form.
676 ///
677 /// The length returned is that of the underlying storage used by `OsStr`.
678 /// As discussed in the [`OsString`] introduction, [`OsString`] and `OsStr`
679 /// store strings in a form best suited for cheap inter-conversion between
680 /// native-platform and Rust string forms, which may differ significantly
681 /// from both of them, including in storage size and encoding.
682 ///
683 /// This number is simply useful for passing to other methods, like
684 /// [`OsString::with_capacity`] to avoid reallocations.
685 ///
686 /// # Examples
687 ///
688 /// ```
689 /// use std::ffi::OsStr;
690 ///
691 /// let os_str = OsStr::new("");
692 /// assert_eq!(os_str.len(), 0);
693 ///
694 /// let os_str = OsStr::new("foo");
695 /// assert_eq!(os_str.len(), 3);
696 /// ```
697 #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
698 #[inline]
699 pub fn len(&self) -> usize {
700 self.inner.inner.len()
701 }
702
703 /// Converts a [`Box`]`<OsStr>` into an [`OsString`] without copying or allocating.
704 #[stable(feature = "into_boxed_os_str", since = "1.20.0")]
705 pub fn into_os_string(self: Box<OsStr>) -> OsString {
706 let boxed = unsafe { Box::from_raw(Box::into_raw(self) as *mut Slice) };
707 OsString { inner: Buf::from_box(boxed) }
708 }
709
710 /// Gets the underlying byte representation.
711 ///
712 /// Note: it is *crucial* that this API is not externally public, to avoid
713 /// revealing the internal, platform-specific encodings.
714 #[inline]
715 pub(crate) fn bytes(&self) -> &[u8] {
716 unsafe { &*(&self.inner as *const _ as *const [u8]) }
717 }
718
719 /// Converts this string to its ASCII lower case equivalent in-place.
720 ///
721 /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
722 /// but non-ASCII letters are unchanged.
723 ///
724 /// To return a new lowercased value without modifying the existing one, use
725 /// [`OsStr::to_ascii_lowercase`].
726 ///
727 /// # Examples
728 ///
729 /// ```
730 /// use std::ffi::OsString;
731 ///
732 /// let mut s = OsString::from("GRÜßE, JÜRGEN ❤");
733 ///
734 /// s.make_ascii_lowercase();
735 ///
736 /// assert_eq!("grÜße, jÜrgen ❤", s);
737 /// ```
738 #[stable(feature = "osstring_ascii", since = "1.53.0")]
739 #[inline]
740 pub fn make_ascii_lowercase(&mut self) {
741 self.inner.make_ascii_lowercase()
742 }
743
744 /// Converts this string to its ASCII upper case equivalent in-place.
745 ///
746 /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
747 /// but non-ASCII letters are unchanged.
748 ///
749 /// To return a new uppercased value without modifying the existing one, use
750 /// [`OsStr::to_ascii_uppercase`].
751 ///
752 /// # Examples
753 ///
754 /// ```
755 /// use std::ffi::OsString;
756 ///
757 /// let mut s = OsString::from("Grüße, Jürgen ❤");
758 ///
759 /// s.make_ascii_uppercase();
760 ///
761 /// assert_eq!("GRüßE, JüRGEN ❤", s);
762 /// ```
763 #[stable(feature = "osstring_ascii", since = "1.53.0")]
764 #[inline]
765 pub fn make_ascii_uppercase(&mut self) {
766 self.inner.make_ascii_uppercase()
767 }
768
769 /// Returns a copy of this string where each character is mapped to its
770 /// ASCII lower case equivalent.
771 ///
772 /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
773 /// but non-ASCII letters are unchanged.
774 ///
775 /// To lowercase the value in-place, use [`OsStr::make_ascii_lowercase`].
776 ///
777 /// # Examples
778 ///
779 /// ```
780 /// use std::ffi::OsString;
781 /// let s = OsString::from("Grüße, Jürgen ❤");
782 ///
783 /// assert_eq!("grüße, jürgen ❤", s.to_ascii_lowercase());
784 /// ```
785 #[stable(feature = "osstring_ascii", since = "1.53.0")]
786 pub fn to_ascii_lowercase(&self) -> OsString {
787 OsString::from_inner(self.inner.to_ascii_lowercase())
788 }
789
790 /// Returns a copy of this string where each character is mapped to its
791 /// ASCII upper case equivalent.
792 ///
793 /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
794 /// but non-ASCII letters are unchanged.
795 ///
796 /// To uppercase the value in-place, use [`OsStr::make_ascii_uppercase`].
797 ///
798 /// # Examples
799 ///
800 /// ```
801 /// use std::ffi::OsString;
802 /// let s = OsString::from("Grüße, Jürgen ❤");
803 ///
804 /// assert_eq!("GRüßE, JüRGEN ❤", s.to_ascii_uppercase());
805 /// ```
806 #[stable(feature = "osstring_ascii", since = "1.53.0")]
807 pub fn to_ascii_uppercase(&self) -> OsString {
808 OsString::from_inner(self.inner.to_ascii_uppercase())
809 }
810
811 /// Checks if all characters in this string are within the ASCII range.
812 ///
813 /// # Examples
814 ///
815 /// ```
816 /// use std::ffi::OsString;
817 ///
818 /// let ascii = OsString::from("hello!\n");
819 /// let non_ascii = OsString::from("Grüße, Jürgen ❤");
820 ///
821 /// assert!(ascii.is_ascii());
822 /// assert!(!non_ascii.is_ascii());
823 /// ```
824 #[stable(feature = "osstring_ascii", since = "1.53.0")]
825 #[inline]
826 pub fn is_ascii(&self) -> bool {
827 self.inner.is_ascii()
828 }
829
830 /// Checks that two strings are an ASCII case-insensitive match.
831 ///
832 /// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`,
833 /// but without allocating and copying temporaries.
834 ///
835 /// # Examples
836 ///
837 /// ```
838 /// use std::ffi::OsString;
839 ///
840 /// assert!(OsString::from("Ferris").eq_ignore_ascii_case("FERRIS"));
841 /// assert!(OsString::from("Ferrös").eq_ignore_ascii_case("FERRöS"));
842 /// assert!(!OsString::from("Ferrös").eq_ignore_ascii_case("FERRÖS"));
843 /// ```
844 #[stable(feature = "osstring_ascii", since = "1.53.0")]
845 pub fn eq_ignore_ascii_case<S: AsRef<OsStr>>(&self, other: S) -> bool {
846 self.inner.eq_ignore_ascii_case(&other.as_ref().inner)
847 }
848 }
849
850 #[stable(feature = "box_from_os_str", since = "1.17.0")]
851 impl From<&OsStr> for Box<OsStr> {
852 #[inline]
853 fn from(s: &OsStr) -> Box<OsStr> {
854 let rw = Box::into_raw(s.inner.into_box()) as *mut OsStr;
855 unsafe { Box::from_raw(rw) }
856 }
857 }
858
859 #[stable(feature = "box_from_cow", since = "1.45.0")]
860 impl From<Cow<'_, OsStr>> for Box<OsStr> {
861 #[inline]
862 fn from(cow: Cow<'_, OsStr>) -> Box<OsStr> {
863 match cow {
864 Cow::Borrowed(s) => Box::from(s),
865 Cow::Owned(s) => Box::from(s),
866 }
867 }
868 }
869
870 #[stable(feature = "os_string_from_box", since = "1.18.0")]
871 impl From<Box<OsStr>> for OsString {
872 /// Converts a [`Box`]`<`[`OsStr`]`>` into an [`OsString`] without copying or
873 /// allocating.
874 #[inline]
875 fn from(boxed: Box<OsStr>) -> OsString {
876 boxed.into_os_string()
877 }
878 }
879
880 #[stable(feature = "box_from_os_string", since = "1.20.0")]
881 impl From<OsString> for Box<OsStr> {
882 /// Converts a [`OsString`] into a [`Box`]`<OsStr>` without copying or allocating.
883 #[inline]
884 fn from(s: OsString) -> Box<OsStr> {
885 s.into_boxed_os_str()
886 }
887 }
888
889 #[stable(feature = "more_box_slice_clone", since = "1.29.0")]
890 impl Clone for Box<OsStr> {
891 #[inline]
892 fn clone(&self) -> Self {
893 self.to_os_string().into_boxed_os_str()
894 }
895 }
896
897 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
898 impl From<OsString> for Arc<OsStr> {
899 /// Converts a [`OsString`] into a [`Arc`]`<OsStr>` without copying or allocating.
900 #[inline]
901 fn from(s: OsString) -> Arc<OsStr> {
902 let arc = s.inner.into_arc();
903 unsafe { Arc::from_raw(Arc::into_raw(arc) as *const OsStr) }
904 }
905 }
906
907 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
908 impl From<&OsStr> for Arc<OsStr> {
909 #[inline]
910 fn from(s: &OsStr) -> Arc<OsStr> {
911 let arc = s.inner.into_arc();
912 unsafe { Arc::from_raw(Arc::into_raw(arc) as *const OsStr) }
913 }
914 }
915
916 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
917 impl From<OsString> for Rc<OsStr> {
918 /// Converts a [`OsString`] into a [`Rc`]`<OsStr>` without copying or allocating.
919 #[inline]
920 fn from(s: OsString) -> Rc<OsStr> {
921 let rc = s.inner.into_rc();
922 unsafe { Rc::from_raw(Rc::into_raw(rc) as *const OsStr) }
923 }
924 }
925
926 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
927 impl From<&OsStr> for Rc<OsStr> {
928 #[inline]
929 fn from(s: &OsStr) -> Rc<OsStr> {
930 let rc = s.inner.into_rc();
931 unsafe { Rc::from_raw(Rc::into_raw(rc) as *const OsStr) }
932 }
933 }
934
935 #[stable(feature = "cow_from_osstr", since = "1.28.0")]
936 impl<'a> From<OsString> for Cow<'a, OsStr> {
937 #[inline]
938 fn from(s: OsString) -> Cow<'a, OsStr> {
939 Cow::Owned(s)
940 }
941 }
942
943 #[stable(feature = "cow_from_osstr", since = "1.28.0")]
944 impl<'a> From<&'a OsStr> for Cow<'a, OsStr> {
945 #[inline]
946 fn from(s: &'a OsStr) -> Cow<'a, OsStr> {
947 Cow::Borrowed(s)
948 }
949 }
950
951 #[stable(feature = "cow_from_osstr", since = "1.28.0")]
952 impl<'a> From<&'a OsString> for Cow<'a, OsStr> {
953 #[inline]
954 fn from(s: &'a OsString) -> Cow<'a, OsStr> {
955 Cow::Borrowed(s.as_os_str())
956 }
957 }
958
959 #[stable(feature = "osstring_from_cow_osstr", since = "1.28.0")]
960 impl<'a> From<Cow<'a, OsStr>> for OsString {
961 #[inline]
962 fn from(s: Cow<'a, OsStr>) -> Self {
963 s.into_owned()
964 }
965 }
966
967 #[stable(feature = "box_default_extra", since = "1.17.0")]
968 impl Default for Box<OsStr> {
969 #[inline]
970 fn default() -> Box<OsStr> {
971 let rw = Box::into_raw(Slice::empty_box()) as *mut OsStr;
972 unsafe { Box::from_raw(rw) }
973 }
974 }
975
976 #[stable(feature = "osstring_default", since = "1.9.0")]
977 impl Default for &OsStr {
978 /// Creates an empty `OsStr`.
979 #[inline]
980 fn default() -> Self {
981 OsStr::new("")
982 }
983 }
984
985 #[stable(feature = "rust1", since = "1.0.0")]
986 impl PartialEq for OsStr {
987 #[inline]
988 fn eq(&self, other: &OsStr) -> bool {
989 self.bytes().eq(other.bytes())
990 }
991 }
992
993 #[stable(feature = "rust1", since = "1.0.0")]
994 impl PartialEq<str> for OsStr {
995 #[inline]
996 fn eq(&self, other: &str) -> bool {
997 *self == *OsStr::new(other)
998 }
999 }
1000
1001 #[stable(feature = "rust1", since = "1.0.0")]
1002 impl PartialEq<OsStr> for str {
1003 #[inline]
1004 fn eq(&self, other: &OsStr) -> bool {
1005 *other == *OsStr::new(self)
1006 }
1007 }
1008
1009 #[stable(feature = "rust1", since = "1.0.0")]
1010 impl Eq for OsStr {}
1011
1012 #[stable(feature = "rust1", since = "1.0.0")]
1013 impl PartialOrd for OsStr {
1014 #[inline]
1015 fn partial_cmp(&self, other: &OsStr) -> Option<cmp::Ordering> {
1016 self.bytes().partial_cmp(other.bytes())
1017 }
1018 #[inline]
1019 fn lt(&self, other: &OsStr) -> bool {
1020 self.bytes().lt(other.bytes())
1021 }
1022 #[inline]
1023 fn le(&self, other: &OsStr) -> bool {
1024 self.bytes().le(other.bytes())
1025 }
1026 #[inline]
1027 fn gt(&self, other: &OsStr) -> bool {
1028 self.bytes().gt(other.bytes())
1029 }
1030 #[inline]
1031 fn ge(&self, other: &OsStr) -> bool {
1032 self.bytes().ge(other.bytes())
1033 }
1034 }
1035
1036 #[stable(feature = "rust1", since = "1.0.0")]
1037 impl PartialOrd<str> for OsStr {
1038 #[inline]
1039 fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
1040 self.partial_cmp(OsStr::new(other))
1041 }
1042 }
1043
1044 // FIXME (#19470): cannot provide PartialOrd<OsStr> for str until we
1045 // have more flexible coherence rules.
1046
1047 #[stable(feature = "rust1", since = "1.0.0")]
1048 impl Ord for OsStr {
1049 #[inline]
1050 fn cmp(&self, other: &OsStr) -> cmp::Ordering {
1051 self.bytes().cmp(other.bytes())
1052 }
1053 }
1054
1055 macro_rules! impl_cmp {
1056 ($lhs:ty, $rhs: ty) => {
1057 #[stable(feature = "cmp_os_str", since = "1.8.0")]
1058 impl<'a, 'b> PartialEq<$rhs> for $lhs {
1059 #[inline]
1060 fn eq(&self, other: &$rhs) -> bool {
1061 <OsStr as PartialEq>::eq(self, other)
1062 }
1063 }
1064
1065 #[stable(feature = "cmp_os_str", since = "1.8.0")]
1066 impl<'a, 'b> PartialEq<$lhs> for $rhs {
1067 #[inline]
1068 fn eq(&self, other: &$lhs) -> bool {
1069 <OsStr as PartialEq>::eq(self, other)
1070 }
1071 }
1072
1073 #[stable(feature = "cmp_os_str", since = "1.8.0")]
1074 impl<'a, 'b> PartialOrd<$rhs> for $lhs {
1075 #[inline]
1076 fn partial_cmp(&self, other: &$rhs) -> Option<cmp::Ordering> {
1077 <OsStr as PartialOrd>::partial_cmp(self, other)
1078 }
1079 }
1080
1081 #[stable(feature = "cmp_os_str", since = "1.8.0")]
1082 impl<'a, 'b> PartialOrd<$lhs> for $rhs {
1083 #[inline]
1084 fn partial_cmp(&self, other: &$lhs) -> Option<cmp::Ordering> {
1085 <OsStr as PartialOrd>::partial_cmp(self, other)
1086 }
1087 }
1088 };
1089 }
1090
1091 impl_cmp!(OsString, OsStr);
1092 impl_cmp!(OsString, &'a OsStr);
1093 impl_cmp!(Cow<'a, OsStr>, OsStr);
1094 impl_cmp!(Cow<'a, OsStr>, &'b OsStr);
1095 impl_cmp!(Cow<'a, OsStr>, OsString);
1096
1097 #[stable(feature = "rust1", since = "1.0.0")]
1098 impl Hash for OsStr {
1099 #[inline]
1100 fn hash<H: Hasher>(&self, state: &mut H) {
1101 self.bytes().hash(state)
1102 }
1103 }
1104
1105 #[stable(feature = "rust1", since = "1.0.0")]
1106 impl fmt::Debug for OsStr {
1107 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1108 fmt::Debug::fmt(&self.inner, formatter)
1109 }
1110 }
1111
1112 impl OsStr {
1113 pub(crate) fn display(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1114 fmt::Display::fmt(&self.inner, formatter)
1115 }
1116 }
1117
1118 #[stable(feature = "rust1", since = "1.0.0")]
1119 impl Borrow<OsStr> for OsString {
1120 #[inline]
1121 fn borrow(&self) -> &OsStr {
1122 &self[..]
1123 }
1124 }
1125
1126 #[stable(feature = "rust1", since = "1.0.0")]
1127 impl ToOwned for OsStr {
1128 type Owned = OsString;
1129 #[inline]
1130 fn to_owned(&self) -> OsString {
1131 self.to_os_string()
1132 }
1133 #[inline]
1134 fn clone_into(&self, target: &mut OsString) {
1135 self.inner.clone_into(&mut target.inner)
1136 }
1137 }
1138
1139 #[stable(feature = "rust1", since = "1.0.0")]
1140 impl AsRef<OsStr> for OsStr {
1141 #[inline]
1142 fn as_ref(&self) -> &OsStr {
1143 self
1144 }
1145 }
1146
1147 #[stable(feature = "rust1", since = "1.0.0")]
1148 impl AsRef<OsStr> for OsString {
1149 #[inline]
1150 fn as_ref(&self) -> &OsStr {
1151 self
1152 }
1153 }
1154
1155 #[stable(feature = "rust1", since = "1.0.0")]
1156 impl AsRef<OsStr> for str {
1157 #[inline]
1158 fn as_ref(&self) -> &OsStr {
1159 OsStr::from_inner(Slice::from_str(self))
1160 }
1161 }
1162
1163 #[stable(feature = "rust1", since = "1.0.0")]
1164 impl AsRef<OsStr> for String {
1165 #[inline]
1166 fn as_ref(&self) -> &OsStr {
1167 (&**self).as_ref()
1168 }
1169 }
1170
1171 impl FromInner<Buf> for OsString {
1172 #[inline]
1173 fn from_inner(buf: Buf) -> OsString {
1174 OsString { inner: buf }
1175 }
1176 }
1177
1178 impl IntoInner<Buf> for OsString {
1179 #[inline]
1180 fn into_inner(self) -> Buf {
1181 self.inner
1182 }
1183 }
1184
1185 impl AsInner<Slice> for OsStr {
1186 #[inline]
1187 fn as_inner(&self) -> &Slice {
1188 &self.inner
1189 }
1190 }
1191
1192 #[stable(feature = "osstring_from_str", since = "1.45.0")]
1193 impl FromStr for OsString {
1194 type Err = core::convert::Infallible;
1195
1196 #[inline]
1197 fn from_str(s: &str) -> Result<Self, Self::Err> {
1198 Ok(OsString::from(s))
1199 }
1200 }
1201
1202 #[stable(feature = "osstring_extend", since = "1.52.0")]
1203 impl Extend<OsString> for OsString {
1204 #[inline]
1205 fn extend<T: IntoIterator<Item = OsString>>(&mut self, iter: T) {
1206 for s in iter {
1207 self.push(&s);
1208 }
1209 }
1210 }
1211
1212 #[stable(feature = "osstring_extend", since = "1.52.0")]
1213 impl<'a> Extend<&'a OsStr> for OsString {
1214 #[inline]
1215 fn extend<T: IntoIterator<Item = &'a OsStr>>(&mut self, iter: T) {
1216 for s in iter {
1217 self.push(s);
1218 }
1219 }
1220 }
1221
1222 #[stable(feature = "osstring_extend", since = "1.52.0")]
1223 impl<'a> Extend<Cow<'a, OsStr>> for OsString {
1224 #[inline]
1225 fn extend<T: IntoIterator<Item = Cow<'a, OsStr>>>(&mut self, iter: T) {
1226 for s in iter {
1227 self.push(&s);
1228 }
1229 }
1230 }
1231
1232 #[stable(feature = "osstring_extend", since = "1.52.0")]
1233 impl FromIterator<OsString> for OsString {
1234 #[inline]
1235 fn from_iter<I: IntoIterator<Item = OsString>>(iter: I) -> Self {
1236 let mut iterator = iter.into_iter();
1237
1238 // Because we're iterating over `OsString`s, we can avoid at least
1239 // one allocation by getting the first string from the iterator
1240 // and appending to it all the subsequent strings.
1241 match iterator.next() {
1242 None => OsString::new(),
1243 Some(mut buf) => {
1244 buf.extend(iterator);
1245 buf
1246 }
1247 }
1248 }
1249 }
1250
1251 #[stable(feature = "osstring_extend", since = "1.52.0")]
1252 impl<'a> FromIterator<&'a OsStr> for OsString {
1253 #[inline]
1254 fn from_iter<I: IntoIterator<Item = &'a OsStr>>(iter: I) -> Self {
1255 let mut buf = Self::new();
1256 for s in iter {
1257 buf.push(s);
1258 }
1259 buf
1260 }
1261 }
1262
1263 #[stable(feature = "osstring_extend", since = "1.52.0")]
1264 impl<'a> FromIterator<Cow<'a, OsStr>> for OsString {
1265 #[inline]
1266 fn from_iter<I: IntoIterator<Item = Cow<'a, OsStr>>>(iter: I) -> Self {
1267 let mut iterator = iter.into_iter();
1268
1269 // Because we're iterating over `OsString`s, we can avoid at least
1270 // one allocation by getting the first owned string from the iterator
1271 // and appending to it all the subsequent strings.
1272 match iterator.next() {
1273 None => OsString::new(),
1274 Some(Cow::Owned(mut buf)) => {
1275 buf.extend(iterator);
1276 buf
1277 }
1278 Some(Cow::Borrowed(buf)) => {
1279 let mut buf = OsString::from(buf);
1280 buf.extend(iterator);
1281 buf
1282 }
1283 }
1284 }
1285 }