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