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