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