]> git.proxmox.com Git - rustc.git/blob - src/libstd/ffi/os_str.rs
New upstream version 1.20.0+dfsg1
[rustc.git] / src / libstd / ffi / os_str.rs
1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use borrow::{Borrow, Cow};
12 use fmt;
13 use mem;
14 use ops;
15 use cmp;
16 use hash::{Hash, Hasher};
17
18 use sys::os_str::{Buf, Slice};
19 use sys_common::{AsInner, IntoInner, FromInner};
20
21 /// A type that can represent owned, mutable platform-native strings, but is
22 /// cheaply inter-convertible with Rust strings.
23 ///
24 /// The need for this type arises from the fact that:
25 ///
26 /// * On Unix systems, strings are often arbitrary sequences of non-zero
27 /// bytes, in many cases interpreted as UTF-8.
28 ///
29 /// * On Windows, strings are often arbitrary sequences of non-zero 16-bit
30 /// values, interpreted as UTF-16 when it is valid to do so.
31 ///
32 /// * In Rust, strings are always valid UTF-8, which may contain zeros.
33 ///
34 /// `OsString` and [`OsStr`] bridge this gap by simultaneously representing Rust
35 /// and platform-native string values, and in particular allowing a Rust string
36 /// to be converted into an "OS" string with no cost.
37 ///
38 /// [`OsStr`]: struct.OsStr.html
39 #[derive(Clone)]
40 #[stable(feature = "rust1", since = "1.0.0")]
41 pub struct OsString {
42 inner: Buf
43 }
44
45 /// Slices into OS strings (see [`OsString`]).
46 ///
47 /// [`OsString`]: struct.OsString.html
48 #[stable(feature = "rust1", since = "1.0.0")]
49 pub struct OsStr {
50 inner: Slice
51 }
52
53 impl OsString {
54 /// Constructs a new empty `OsString`.
55 ///
56 /// # Examples
57 ///
58 /// ```
59 /// use std::ffi::OsString;
60 ///
61 /// let os_string = OsString::new();
62 /// ```
63 #[stable(feature = "rust1", since = "1.0.0")]
64 pub fn new() -> OsString {
65 OsString { inner: Buf::from_string(String::new()) }
66 }
67
68 /// Converts to an [`OsStr`] slice.
69 ///
70 /// [`OsStr`]: struct.OsStr.html
71 ///
72 /// # Examples
73 ///
74 /// ```
75 /// use std::ffi::{OsString, OsStr};
76 ///
77 /// let os_string = OsString::from("foo");
78 /// let os_str = OsStr::new("foo");
79 /// assert_eq!(os_string.as_os_str(), os_str);
80 /// ```
81 #[stable(feature = "rust1", since = "1.0.0")]
82 pub fn as_os_str(&self) -> &OsStr {
83 self
84 }
85
86 /// Converts the `OsString` into a [`String`] if it contains valid Unicode data.
87 ///
88 /// On failure, ownership of the original `OsString` is returned.
89 ///
90 /// [`String`]: ../../std/string/struct.String.html
91 ///
92 /// # Examples
93 ///
94 /// ```
95 /// use std::ffi::OsString;
96 ///
97 /// let os_string = OsString::from("foo");
98 /// let string = os_string.into_string();
99 /// assert_eq!(string, Ok(String::from("foo")));
100 /// ```
101 #[stable(feature = "rust1", since = "1.0.0")]
102 pub fn into_string(self) -> Result<String, OsString> {
103 self.inner.into_string().map_err(|buf| OsString { inner: buf} )
104 }
105
106 /// Extends the string with the given [`&OsStr`] slice.
107 ///
108 /// [`&OsStr`]: struct.OsStr.html
109 ///
110 /// # Examples
111 ///
112 /// ```
113 /// use std::ffi::OsString;
114 ///
115 /// let mut os_string = OsString::from("foo");
116 /// os_string.push("bar");
117 /// assert_eq!(&os_string, "foobar");
118 /// ```
119 #[stable(feature = "rust1", since = "1.0.0")]
120 pub fn push<T: AsRef<OsStr>>(&mut self, s: T) {
121 self.inner.push_slice(&s.as_ref().inner)
122 }
123
124 /// Creates a new `OsString` with the given capacity.
125 ///
126 /// The string will be able to hold exactly `capacity` lenth units of other
127 /// OS strings without reallocating. If `capacity` is 0, the string will not
128 /// allocate.
129 ///
130 /// See main `OsString` documentation information about encoding.
131 ///
132 /// # Examples
133 ///
134 /// ```
135 /// use std::ffi::OsString;
136 ///
137 /// let mut os_string = OsString::with_capacity(10);
138 /// let capacity = os_string.capacity();
139 ///
140 /// // This push is done without reallocating
141 /// os_string.push("foo");
142 ///
143 /// assert_eq!(capacity, os_string.capacity());
144 /// ```
145 #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
146 pub fn with_capacity(capacity: usize) -> OsString {
147 OsString {
148 inner: Buf::with_capacity(capacity)
149 }
150 }
151
152 /// Truncates the `OsString` to zero length.
153 ///
154 /// # Examples
155 ///
156 /// ```
157 /// use std::ffi::OsString;
158 ///
159 /// let mut os_string = OsString::from("foo");
160 /// assert_eq!(&os_string, "foo");
161 ///
162 /// os_string.clear();
163 /// assert_eq!(&os_string, "");
164 /// ```
165 #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
166 pub fn clear(&mut self) {
167 self.inner.clear()
168 }
169
170 /// Returns the capacity this `OsString` can hold without reallocating.
171 ///
172 /// See `OsString` introduction for information about encoding.
173 ///
174 /// # Examples
175 ///
176 /// ```
177 /// use std::ffi::OsString;
178 ///
179 /// let mut os_string = OsString::with_capacity(10);
180 /// assert!(os_string.capacity() >= 10);
181 /// ```
182 #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
183 pub fn capacity(&self) -> usize {
184 self.inner.capacity()
185 }
186
187 /// Reserves capacity for at least `additional` more capacity to be inserted
188 /// in the given `OsString`.
189 ///
190 /// The collection may reserve more space to avoid frequent reallocations.
191 ///
192 /// # Examples
193 ///
194 /// ```
195 /// use std::ffi::OsString;
196 ///
197 /// let mut s = OsString::new();
198 /// s.reserve(10);
199 /// assert!(s.capacity() >= 10);
200 /// ```
201 #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
202 pub fn reserve(&mut self, additional: usize) {
203 self.inner.reserve(additional)
204 }
205
206 /// Reserves the minimum capacity for exactly `additional` more capacity to
207 /// be inserted in the given `OsString`. Does nothing if the capacity is
208 /// already sufficient.
209 ///
210 /// Note that the allocator may give the collection more space than it
211 /// requests. Therefore capacity can not be relied upon to be precisely
212 /// minimal. Prefer reserve if future insertions are expected.
213 ///
214 /// # Examples
215 ///
216 /// ```
217 /// use std::ffi::OsString;
218 ///
219 /// let mut s = OsString::new();
220 /// s.reserve_exact(10);
221 /// assert!(s.capacity() >= 10);
222 /// ```
223 #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
224 pub fn reserve_exact(&mut self, additional: usize) {
225 self.inner.reserve_exact(additional)
226 }
227
228 /// Shrinks the capacity of the `OsString` to match its length.
229 ///
230 /// # Examples
231 ///
232 /// ```
233 /// use std::ffi::OsString;
234 ///
235 /// let mut s = OsString::from("foo");
236 ///
237 /// s.reserve(100);
238 /// assert!(s.capacity() >= 100);
239 ///
240 /// s.shrink_to_fit();
241 /// assert_eq!(3, s.capacity());
242 /// ```
243 #[stable(feature = "osstring_shrink_to_fit", since = "1.19.0")]
244 pub fn shrink_to_fit(&mut self) {
245 self.inner.shrink_to_fit()
246 }
247
248 /// Converts this `OsString` into a boxed [`OsStr`].
249 ///
250 /// [`OsStr`]: struct.OsStr.html
251 ///
252 /// # Examples
253 ///
254 /// ```
255 /// use std::ffi::{OsString, OsStr};
256 ///
257 /// let s = OsString::from("hello");
258 ///
259 /// let b: Box<OsStr> = s.into_boxed_os_str();
260 /// ```
261 #[stable(feature = "into_boxed_os_str", since = "1.20.0")]
262 pub fn into_boxed_os_str(self) -> Box<OsStr> {
263 unsafe { mem::transmute(self.inner.into_box()) }
264 }
265 }
266
267 #[stable(feature = "rust1", since = "1.0.0")]
268 impl From<String> for OsString {
269 fn from(s: String) -> OsString {
270 OsString { inner: Buf::from_string(s) }
271 }
272 }
273
274 #[stable(feature = "rust1", since = "1.0.0")]
275 impl<'a, T: ?Sized + AsRef<OsStr>> From<&'a T> for OsString {
276 fn from(s: &'a T) -> OsString {
277 s.as_ref().to_os_string()
278 }
279 }
280
281 #[stable(feature = "rust1", since = "1.0.0")]
282 impl ops::Index<ops::RangeFull> for OsString {
283 type Output = OsStr;
284
285 #[inline]
286 fn index(&self, _index: ops::RangeFull) -> &OsStr {
287 OsStr::from_inner(self.inner.as_slice())
288 }
289 }
290
291 #[stable(feature = "rust1", since = "1.0.0")]
292 impl ops::Deref for OsString {
293 type Target = OsStr;
294
295 #[inline]
296 fn deref(&self) -> &OsStr {
297 &self[..]
298 }
299 }
300
301 #[stable(feature = "osstring_default", since = "1.9.0")]
302 impl Default for OsString {
303 /// Constructs an empty `OsString`.
304 #[inline]
305 fn default() -> OsString {
306 OsString::new()
307 }
308 }
309
310 #[stable(feature = "rust1", since = "1.0.0")]
311 impl fmt::Debug for OsString {
312 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
313 fmt::Debug::fmt(&**self, formatter)
314 }
315 }
316
317 #[stable(feature = "rust1", since = "1.0.0")]
318 impl PartialEq for OsString {
319 fn eq(&self, other: &OsString) -> bool {
320 &**self == &**other
321 }
322 }
323
324 #[stable(feature = "rust1", since = "1.0.0")]
325 impl PartialEq<str> for OsString {
326 fn eq(&self, other: &str) -> bool {
327 &**self == other
328 }
329 }
330
331 #[stable(feature = "rust1", since = "1.0.0")]
332 impl PartialEq<OsString> for str {
333 fn eq(&self, other: &OsString) -> bool {
334 &**other == self
335 }
336 }
337
338 #[stable(feature = "rust1", since = "1.0.0")]
339 impl Eq for OsString {}
340
341 #[stable(feature = "rust1", since = "1.0.0")]
342 impl PartialOrd for OsString {
343 #[inline]
344 fn partial_cmp(&self, other: &OsString) -> Option<cmp::Ordering> {
345 (&**self).partial_cmp(&**other)
346 }
347 #[inline]
348 fn lt(&self, other: &OsString) -> bool { &**self < &**other }
349 #[inline]
350 fn le(&self, other: &OsString) -> bool { &**self <= &**other }
351 #[inline]
352 fn gt(&self, other: &OsString) -> bool { &**self > &**other }
353 #[inline]
354 fn ge(&self, other: &OsString) -> bool { &**self >= &**other }
355 }
356
357 #[stable(feature = "rust1", since = "1.0.0")]
358 impl PartialOrd<str> for OsString {
359 #[inline]
360 fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
361 (&**self).partial_cmp(other)
362 }
363 }
364
365 #[stable(feature = "rust1", since = "1.0.0")]
366 impl Ord for OsString {
367 #[inline]
368 fn cmp(&self, other: &OsString) -> cmp::Ordering {
369 (&**self).cmp(&**other)
370 }
371 }
372
373 #[stable(feature = "rust1", since = "1.0.0")]
374 impl Hash for OsString {
375 #[inline]
376 fn hash<H: Hasher>(&self, state: &mut H) {
377 (&**self).hash(state)
378 }
379 }
380
381 impl OsStr {
382 /// Coerces into an `OsStr` slice.
383 ///
384 /// # Examples
385 ///
386 /// ```
387 /// use std::ffi::OsStr;
388 ///
389 /// let os_str = OsStr::new("foo");
390 /// ```
391 #[stable(feature = "rust1", since = "1.0.0")]
392 pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &OsStr {
393 s.as_ref()
394 }
395
396 fn from_inner(inner: &Slice) -> &OsStr {
397 unsafe { mem::transmute(inner) }
398 }
399
400 /// Yields a [`&str`] slice if the `OsStr` is valid Unicode.
401 ///
402 /// This conversion may entail doing a check for UTF-8 validity.
403 ///
404 /// [`&str`]: ../../std/primitive.str.html
405 ///
406 /// # Examples
407 ///
408 /// ```
409 /// use std::ffi::OsStr;
410 ///
411 /// let os_str = OsStr::new("foo");
412 /// assert_eq!(os_str.to_str(), Some("foo"));
413 /// ```
414 #[stable(feature = "rust1", since = "1.0.0")]
415 pub fn to_str(&self) -> Option<&str> {
416 self.inner.to_str()
417 }
418
419 /// Converts an `OsStr` to a [`Cow`]`<`[`str`]`>`.
420 ///
421 /// Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER.
422 ///
423 /// [`Cow`]: ../../std/borrow/enum.Cow.html
424 /// [`str`]: ../../std/primitive.str.html
425 ///
426 /// # Examples
427 ///
428 /// Calling `to_string_lossy` on an `OsStr` with valid unicode:
429 ///
430 /// ```
431 /// use std::ffi::OsStr;
432 ///
433 /// let os_str = OsStr::new("foo");
434 /// assert_eq!(os_str.to_string_lossy(), "foo");
435 /// ```
436 ///
437 /// Had `os_str` contained invalid unicode, the `to_string_lossy` call might
438 /// have returned `"fo�"`.
439 #[stable(feature = "rust1", since = "1.0.0")]
440 pub fn to_string_lossy(&self) -> Cow<str> {
441 self.inner.to_string_lossy()
442 }
443
444 /// Copies the slice into an owned [`OsString`].
445 ///
446 /// [`OsString`]: struct.OsString.html
447 ///
448 /// # Examples
449 ///
450 /// ```
451 /// use std::ffi::{OsStr, OsString};
452 ///
453 /// let os_str = OsStr::new("foo");
454 /// let os_string = os_str.to_os_string();
455 /// assert_eq!(os_string, OsString::from("foo"));
456 /// ```
457 #[stable(feature = "rust1", since = "1.0.0")]
458 pub fn to_os_string(&self) -> OsString {
459 OsString { inner: self.inner.to_owned() }
460 }
461
462 /// Checks whether the `OsStr` is empty.
463 ///
464 /// # Examples
465 ///
466 /// ```
467 /// use std::ffi::OsStr;
468 ///
469 /// let os_str = OsStr::new("");
470 /// assert!(os_str.is_empty());
471 ///
472 /// let os_str = OsStr::new("foo");
473 /// assert!(!os_str.is_empty());
474 /// ```
475 #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
476 pub fn is_empty(&self) -> bool {
477 self.inner.inner.is_empty()
478 }
479
480 /// Returns the length of this `OsStr`.
481 ///
482 /// Note that this does **not** return the number of bytes in this string
483 /// as, for example, OS strings on Windows are encoded as a list of [`u16`]
484 /// rather than a list of bytes. This number is simply useful for passing to
485 /// other methods like [`OsString::with_capacity`] to avoid reallocations.
486 ///
487 /// See `OsStr` introduction for more information about encoding.
488 ///
489 /// [`u16`]: ../primitive.u16.html
490 /// [`OsString::with_capacity`]: struct.OsString.html#method.with_capacity
491 ///
492 /// # Examples
493 ///
494 /// ```
495 /// use std::ffi::OsStr;
496 ///
497 /// let os_str = OsStr::new("");
498 /// assert_eq!(os_str.len(), 0);
499 ///
500 /// let os_str = OsStr::new("foo");
501 /// assert_eq!(os_str.len(), 3);
502 /// ```
503 #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
504 pub fn len(&self) -> usize {
505 self.inner.inner.len()
506 }
507
508 /// Converts a [`Box`]`<OsStr>` into an [`OsString`] without copying or allocating.
509 ///
510 /// [`Box`]: ../boxed/struct.Box.html
511 /// [`OsString`]: struct.OsString.html
512 #[stable(feature = "into_boxed_os_str", since = "1.20.0")]
513 pub fn into_os_string(self: Box<OsStr>) -> OsString {
514 let inner: Box<Slice> = unsafe { mem::transmute(self) };
515 OsString { inner: Buf::from_box(inner) }
516 }
517
518 /// Gets the underlying byte representation.
519 ///
520 /// Note: it is *crucial* that this API is private, to avoid
521 /// revealing the internal, platform-specific encodings.
522 fn bytes(&self) -> &[u8] {
523 unsafe { mem::transmute(&self.inner) }
524 }
525 }
526
527 #[stable(feature = "box_from_os_str", since = "1.17.0")]
528 impl<'a> From<&'a OsStr> for Box<OsStr> {
529 fn from(s: &'a OsStr) -> Box<OsStr> {
530 unsafe { mem::transmute(s.inner.into_box()) }
531 }
532 }
533
534 #[stable(feature = "os_string_from_box", since = "1.18.0")]
535 impl From<Box<OsStr>> for OsString {
536 fn from(boxed: Box<OsStr>) -> OsString {
537 boxed.into_os_string()
538 }
539 }
540
541 #[stable(feature = "box_from_os_string", since = "1.20.0")]
542 impl From<OsString> for Box<OsStr> {
543 fn from(s: OsString) -> Box<OsStr> {
544 s.into_boxed_os_str()
545 }
546 }
547
548 #[stable(feature = "box_default_extra", since = "1.17.0")]
549 impl Default for Box<OsStr> {
550 fn default() -> Box<OsStr> {
551 unsafe { mem::transmute(Slice::empty_box()) }
552 }
553 }
554
555 #[stable(feature = "osstring_default", since = "1.9.0")]
556 impl<'a> Default for &'a OsStr {
557 /// Creates an empty `OsStr`.
558 #[inline]
559 fn default() -> &'a OsStr {
560 OsStr::new("")
561 }
562 }
563
564 #[stable(feature = "rust1", since = "1.0.0")]
565 impl PartialEq for OsStr {
566 fn eq(&self, other: &OsStr) -> bool {
567 self.bytes().eq(other.bytes())
568 }
569 }
570
571 #[stable(feature = "rust1", since = "1.0.0")]
572 impl PartialEq<str> for OsStr {
573 fn eq(&self, other: &str) -> bool {
574 *self == *OsStr::new(other)
575 }
576 }
577
578 #[stable(feature = "rust1", since = "1.0.0")]
579 impl PartialEq<OsStr> for str {
580 fn eq(&self, other: &OsStr) -> bool {
581 *other == *OsStr::new(self)
582 }
583 }
584
585 #[stable(feature = "rust1", since = "1.0.0")]
586 impl Eq for OsStr {}
587
588 #[stable(feature = "rust1", since = "1.0.0")]
589 impl PartialOrd for OsStr {
590 #[inline]
591 fn partial_cmp(&self, other: &OsStr) -> Option<cmp::Ordering> {
592 self.bytes().partial_cmp(other.bytes())
593 }
594 #[inline]
595 fn lt(&self, other: &OsStr) -> bool { self.bytes().lt(other.bytes()) }
596 #[inline]
597 fn le(&self, other: &OsStr) -> bool { self.bytes().le(other.bytes()) }
598 #[inline]
599 fn gt(&self, other: &OsStr) -> bool { self.bytes().gt(other.bytes()) }
600 #[inline]
601 fn ge(&self, other: &OsStr) -> bool { self.bytes().ge(other.bytes()) }
602 }
603
604 #[stable(feature = "rust1", since = "1.0.0")]
605 impl PartialOrd<str> for OsStr {
606 #[inline]
607 fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
608 self.partial_cmp(OsStr::new(other))
609 }
610 }
611
612 // FIXME (#19470): cannot provide PartialOrd<OsStr> for str until we
613 // have more flexible coherence rules.
614
615 #[stable(feature = "rust1", since = "1.0.0")]
616 impl Ord for OsStr {
617 #[inline]
618 fn cmp(&self, other: &OsStr) -> cmp::Ordering { self.bytes().cmp(other.bytes()) }
619 }
620
621 macro_rules! impl_cmp {
622 ($lhs:ty, $rhs: ty) => {
623 #[stable(feature = "cmp_os_str", since = "1.8.0")]
624 impl<'a, 'b> PartialEq<$rhs> for $lhs {
625 #[inline]
626 fn eq(&self, other: &$rhs) -> bool { <OsStr as PartialEq>::eq(self, other) }
627 }
628
629 #[stable(feature = "cmp_os_str", since = "1.8.0")]
630 impl<'a, 'b> PartialEq<$lhs> for $rhs {
631 #[inline]
632 fn eq(&self, other: &$lhs) -> bool { <OsStr as PartialEq>::eq(self, other) }
633 }
634
635 #[stable(feature = "cmp_os_str", since = "1.8.0")]
636 impl<'a, 'b> PartialOrd<$rhs> for $lhs {
637 #[inline]
638 fn partial_cmp(&self, other: &$rhs) -> Option<cmp::Ordering> {
639 <OsStr as PartialOrd>::partial_cmp(self, other)
640 }
641 }
642
643 #[stable(feature = "cmp_os_str", since = "1.8.0")]
644 impl<'a, 'b> PartialOrd<$lhs> for $rhs {
645 #[inline]
646 fn partial_cmp(&self, other: &$lhs) -> Option<cmp::Ordering> {
647 <OsStr as PartialOrd>::partial_cmp(self, other)
648 }
649 }
650 }
651 }
652
653 impl_cmp!(OsString, OsStr);
654 impl_cmp!(OsString, &'a OsStr);
655 impl_cmp!(Cow<'a, OsStr>, OsStr);
656 impl_cmp!(Cow<'a, OsStr>, &'b OsStr);
657 impl_cmp!(Cow<'a, OsStr>, OsString);
658
659 #[stable(feature = "rust1", since = "1.0.0")]
660 impl Hash for OsStr {
661 #[inline]
662 fn hash<H: Hasher>(&self, state: &mut H) {
663 self.bytes().hash(state)
664 }
665 }
666
667 #[stable(feature = "rust1", since = "1.0.0")]
668 impl fmt::Debug for OsStr {
669 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
670 fmt::Debug::fmt(&self.inner, formatter)
671 }
672 }
673
674 impl OsStr {
675 pub(crate) fn display(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
676 fmt::Display::fmt(&self.inner, formatter)
677 }
678 }
679
680 #[stable(feature = "rust1", since = "1.0.0")]
681 impl Borrow<OsStr> for OsString {
682 fn borrow(&self) -> &OsStr { &self[..] }
683 }
684
685 #[stable(feature = "rust1", since = "1.0.0")]
686 impl ToOwned for OsStr {
687 type Owned = OsString;
688 fn to_owned(&self) -> OsString {
689 self.to_os_string()
690 }
691 fn clone_into(&self, target: &mut OsString) {
692 target.clear();
693 target.push(self);
694 }
695 }
696
697 #[stable(feature = "rust1", since = "1.0.0")]
698 impl AsRef<OsStr> for OsStr {
699 fn as_ref(&self) -> &OsStr {
700 self
701 }
702 }
703
704 #[stable(feature = "rust1", since = "1.0.0")]
705 impl AsRef<OsStr> for OsString {
706 fn as_ref(&self) -> &OsStr {
707 self
708 }
709 }
710
711 #[stable(feature = "rust1", since = "1.0.0")]
712 impl AsRef<OsStr> for str {
713 fn as_ref(&self) -> &OsStr {
714 OsStr::from_inner(Slice::from_str(self))
715 }
716 }
717
718 #[stable(feature = "rust1", since = "1.0.0")]
719 impl AsRef<OsStr> for String {
720 fn as_ref(&self) -> &OsStr {
721 (&**self).as_ref()
722 }
723 }
724
725 impl FromInner<Buf> for OsString {
726 fn from_inner(buf: Buf) -> OsString {
727 OsString { inner: buf }
728 }
729 }
730
731 impl IntoInner<Buf> for OsString {
732 fn into_inner(self) -> Buf {
733 self.inner
734 }
735 }
736
737 impl AsInner<Slice> for OsStr {
738 fn as_inner(&self) -> &Slice {
739 &self.inner
740 }
741 }
742
743 #[cfg(test)]
744 mod tests {
745 use super::*;
746 use sys_common::{AsInner, IntoInner};
747
748 #[test]
749 fn test_os_string_with_capacity() {
750 let os_string = OsString::with_capacity(0);
751 assert_eq!(0, os_string.inner.into_inner().capacity());
752
753 let os_string = OsString::with_capacity(10);
754 assert_eq!(10, os_string.inner.into_inner().capacity());
755
756 let mut os_string = OsString::with_capacity(0);
757 os_string.push("abc");
758 assert!(os_string.inner.into_inner().capacity() >= 3);
759 }
760
761 #[test]
762 fn test_os_string_clear() {
763 let mut os_string = OsString::from("abc");
764 assert_eq!(3, os_string.inner.as_inner().len());
765
766 os_string.clear();
767 assert_eq!(&os_string, "");
768 assert_eq!(0, os_string.inner.as_inner().len());
769 }
770
771 #[test]
772 fn test_os_string_capacity() {
773 let os_string = OsString::with_capacity(0);
774 assert_eq!(0, os_string.capacity());
775
776 let os_string = OsString::with_capacity(10);
777 assert_eq!(10, os_string.capacity());
778
779 let mut os_string = OsString::with_capacity(0);
780 os_string.push("abc");
781 assert!(os_string.capacity() >= 3);
782 }
783
784 #[test]
785 fn test_os_string_reserve() {
786 let mut os_string = OsString::new();
787 assert_eq!(os_string.capacity(), 0);
788
789 os_string.reserve(2);
790 assert!(os_string.capacity() >= 2);
791
792 for _ in 0..16 {
793 os_string.push("a");
794 }
795
796 assert!(os_string.capacity() >= 16);
797 os_string.reserve(16);
798 assert!(os_string.capacity() >= 32);
799
800 os_string.push("a");
801
802 os_string.reserve(16);
803 assert!(os_string.capacity() >= 33)
804 }
805
806 #[test]
807 fn test_os_string_reserve_exact() {
808 let mut os_string = OsString::new();
809 assert_eq!(os_string.capacity(), 0);
810
811 os_string.reserve_exact(2);
812 assert!(os_string.capacity() >= 2);
813
814 for _ in 0..16 {
815 os_string.push("a");
816 }
817
818 assert!(os_string.capacity() >= 16);
819 os_string.reserve_exact(16);
820 assert!(os_string.capacity() >= 32);
821
822 os_string.push("a");
823
824 os_string.reserve_exact(16);
825 assert!(os_string.capacity() >= 33)
826 }
827
828 #[test]
829 fn test_os_string_default() {
830 let os_string: OsString = Default::default();
831 assert_eq!("", &os_string);
832 }
833
834 #[test]
835 fn test_os_str_is_empty() {
836 let mut os_string = OsString::new();
837 assert!(os_string.is_empty());
838
839 os_string.push("abc");
840 assert!(!os_string.is_empty());
841
842 os_string.clear();
843 assert!(os_string.is_empty());
844 }
845
846 #[test]
847 fn test_os_str_len() {
848 let mut os_string = OsString::new();
849 assert_eq!(0, os_string.len());
850
851 os_string.push("abc");
852 assert_eq!(3, os_string.len());
853
854 os_string.clear();
855 assert_eq!(0, os_string.len());
856 }
857
858 #[test]
859 fn test_os_str_default() {
860 let os_str: &OsStr = Default::default();
861 assert_eq!("", os_str);
862 }
863
864 #[test]
865 fn into_boxed() {
866 let orig = "Hello, world!";
867 let os_str = OsStr::new(orig);
868 let boxed: Box<OsStr> = Box::from(os_str);
869 let os_string = os_str.to_owned().into_boxed_os_str().into_os_string();
870 assert_eq!(os_str, &*boxed);
871 assert_eq!(&*boxed, &*os_string);
872 assert_eq!(&*os_string, os_str);
873 }
874
875 #[test]
876 fn boxed_default() {
877 let boxed = <Box<OsStr>>::default();
878 assert!(boxed.is_empty());
879 }
880
881 #[test]
882 fn test_os_str_clone_into() {
883 let mut os_string = OsString::with_capacity(123);
884 os_string.push("hello");
885 let os_str = OsStr::new("bonjour");
886 os_str.clone_into(&mut os_string);
887 assert_eq!(os_str, os_string);
888 assert!(os_string.capacity() >= 123);
889 }
890 }