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