]> git.lizzy.rs Git - rust.git/blob - src/libstd/ffi/os_str.rs
Add From<Box<..>> implementations.
[rust.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::{self, Debug};
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, but 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     #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
192     pub fn reserve(&mut self, additional: usize) {
193         self.inner.reserve(additional)
194     }
195
196     /// Reserves the minimum capacity for exactly `additional` more capacity to
197     /// be inserted in the given `OsString`. Does nothing if the capacity is
198     /// already sufficient.
199     ///
200     /// Note that the allocator may give the collection more space than it
201     /// requests. Therefore capacity can not be relied upon to be precisely
202     /// minimal. Prefer reserve if future insertions are expected.
203     #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
204     pub fn reserve_exact(&mut self, additional: usize) {
205         self.inner.reserve_exact(additional)
206     }
207
208     /// Converts this `OsString` into a boxed `OsStr`.
209     #[unstable(feature = "into_boxed_os_str", issue = "40380")]
210     pub fn into_boxed_os_str(self) -> Box<OsStr> {
211         unsafe { mem::transmute(self.inner.into_box()) }
212     }
213 }
214
215 #[stable(feature = "rust1", since = "1.0.0")]
216 impl From<String> for OsString {
217     fn from(s: String) -> OsString {
218         OsString { inner: Buf::from_string(s) }
219     }
220 }
221
222 #[stable(feature = "rust1", since = "1.0.0")]
223 impl<'a, T: ?Sized + AsRef<OsStr>> From<&'a T> for OsString {
224     fn from(s: &'a T) -> OsString {
225         s.as_ref().to_os_string()
226     }
227 }
228
229 #[stable(feature = "rust1", since = "1.0.0")]
230 impl ops::Index<ops::RangeFull> for OsString {
231     type Output = OsStr;
232
233     #[inline]
234     fn index(&self, _index: ops::RangeFull) -> &OsStr {
235         OsStr::from_inner(self.inner.as_slice())
236     }
237 }
238
239 #[stable(feature = "rust1", since = "1.0.0")]
240 impl ops::Deref for OsString {
241     type Target = OsStr;
242
243     #[inline]
244     fn deref(&self) -> &OsStr {
245         &self[..]
246     }
247 }
248
249 #[stable(feature = "osstring_default", since = "1.9.0")]
250 impl Default for OsString {
251     /// Constructs an empty `OsString`.
252     #[inline]
253     fn default() -> OsString {
254         OsString::new()
255     }
256 }
257
258 #[stable(feature = "rust1", since = "1.0.0")]
259 impl Debug for OsString {
260     fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
261         fmt::Debug::fmt(&**self, formatter)
262     }
263 }
264
265 #[stable(feature = "rust1", since = "1.0.0")]
266 impl PartialEq for OsString {
267     fn eq(&self, other: &OsString) -> bool {
268         &**self == &**other
269     }
270 }
271
272 #[stable(feature = "rust1", since = "1.0.0")]
273 impl PartialEq<str> for OsString {
274     fn eq(&self, other: &str) -> bool {
275         &**self == other
276     }
277 }
278
279 #[stable(feature = "rust1", since = "1.0.0")]
280 impl PartialEq<OsString> for str {
281     fn eq(&self, other: &OsString) -> bool {
282         &**other == self
283     }
284 }
285
286 #[stable(feature = "rust1", since = "1.0.0")]
287 impl Eq for OsString {}
288
289 #[stable(feature = "rust1", since = "1.0.0")]
290 impl PartialOrd for OsString {
291     #[inline]
292     fn partial_cmp(&self, other: &OsString) -> Option<cmp::Ordering> {
293         (&**self).partial_cmp(&**other)
294     }
295     #[inline]
296     fn lt(&self, other: &OsString) -> bool { &**self < &**other }
297     #[inline]
298     fn le(&self, other: &OsString) -> bool { &**self <= &**other }
299     #[inline]
300     fn gt(&self, other: &OsString) -> bool { &**self > &**other }
301     #[inline]
302     fn ge(&self, other: &OsString) -> bool { &**self >= &**other }
303 }
304
305 #[stable(feature = "rust1", since = "1.0.0")]
306 impl PartialOrd<str> for OsString {
307     #[inline]
308     fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
309         (&**self).partial_cmp(other)
310     }
311 }
312
313 #[stable(feature = "rust1", since = "1.0.0")]
314 impl Ord for OsString {
315     #[inline]
316     fn cmp(&self, other: &OsString) -> cmp::Ordering {
317         (&**self).cmp(&**other)
318     }
319 }
320
321 #[stable(feature = "rust1", since = "1.0.0")]
322 impl Hash for OsString {
323     #[inline]
324     fn hash<H: Hasher>(&self, state: &mut H) {
325         (&**self).hash(state)
326     }
327 }
328
329 impl OsStr {
330     /// Coerces into an `OsStr` slice.
331     ///
332     /// # Examples
333     ///
334     /// ```
335     /// use std::ffi::OsStr;
336     ///
337     /// let os_str = OsStr::new("foo");
338     /// ```
339     #[stable(feature = "rust1", since = "1.0.0")]
340     pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &OsStr {
341         s.as_ref()
342     }
343
344     fn from_inner(inner: &Slice) -> &OsStr {
345         unsafe { mem::transmute(inner) }
346     }
347
348     /// Yields a [`&str`] slice if the `OsStr` is valid Unicode.
349     ///
350     /// This conversion may entail doing a check for UTF-8 validity.
351     ///
352     /// [`&str`]: ../../std/primitive.str.html
353     ///
354     /// # Examples
355     ///
356     /// ```
357     /// use std::ffi::OsStr;
358     ///
359     /// let os_str = OsStr::new("foo");
360     /// assert_eq!(os_str.to_str(), Some("foo"));
361     /// ```
362     #[stable(feature = "rust1", since = "1.0.0")]
363     pub fn to_str(&self) -> Option<&str> {
364         self.inner.to_str()
365     }
366
367     /// Converts an `OsStr` to a [`Cow`]`<`[`str`]`>`.
368     ///
369     /// Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER.
370     ///
371     /// [`Cow`]: ../../std/borrow/enum.Cow.html
372     /// [`str`]: ../../std/primitive.str.html
373     ///
374     /// # Examples
375     ///
376     /// Calling `to_string_lossy` on an `OsStr` with valid unicode:
377     ///
378     /// ```
379     /// use std::ffi::OsStr;
380     ///
381     /// let os_str = OsStr::new("foo");
382     /// assert_eq!(os_str.to_string_lossy(), "foo");
383     /// ```
384     ///
385     /// Had `os_str` contained invalid unicode, the `to_string_lossy` call might
386     /// have returned `"fo�"`.
387     #[stable(feature = "rust1", since = "1.0.0")]
388     pub fn to_string_lossy(&self) -> Cow<str> {
389         self.inner.to_string_lossy()
390     }
391
392     /// Copies the slice into an owned [`OsString`].
393     ///
394     /// [`OsString`]: struct.OsString.html
395     #[stable(feature = "rust1", since = "1.0.0")]
396     pub fn to_os_string(&self) -> OsString {
397         OsString { inner: self.inner.to_owned() }
398     }
399
400     /// Checks whether the `OsStr` is empty.
401     ///
402     /// # Examples
403     ///
404     /// ```
405     /// use std::ffi::OsStr;
406     ///
407     /// let os_str = OsStr::new("");
408     /// assert!(os_str.is_empty());
409     ///
410     /// let os_str = OsStr::new("foo");
411     /// assert!(!os_str.is_empty());
412     /// ```
413     #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
414     pub fn is_empty(&self) -> bool {
415         self.inner.inner.is_empty()
416     }
417
418     /// Returns the length of this `OsStr`.
419     ///
420     /// Note that this does **not** return the number of bytes in this string
421     /// as, for example, OS strings on Windows are encoded as a list of `u16`
422     /// rather than a list of bytes. This number is simply useful for passing to
423     /// other methods like [`OsString::with_capacity`] to avoid reallocations.
424     ///
425     /// See `OsStr` introduction for more information about encoding.
426     ///
427     /// [`OsString::with_capacity`]: struct.OsString.html#method.with_capacity
428     ///
429     /// # Examples
430     ///
431     /// ```
432     /// use std::ffi::OsStr;
433     ///
434     /// let os_str = OsStr::new("");
435     /// assert_eq!(os_str.len(), 0);
436     ///
437     /// let os_str = OsStr::new("foo");
438     /// assert_eq!(os_str.len(), 3);
439     /// ```
440     #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
441     pub fn len(&self) -> usize {
442         self.inner.inner.len()
443     }
444
445     /// Converts a `Box<OsStr>` into an `OsString` without copying or allocating.
446     #[unstable(feature = "into_boxed_os_str", issue = "40380")]
447     pub fn into_os_string(self: Box<OsStr>) -> OsString {
448         let inner: Box<Slice> = unsafe { mem::transmute(self) };
449         OsString { inner: Buf::from_box(inner) }
450     }
451
452     /// Gets the underlying byte representation.
453     ///
454     /// Note: it is *crucial* that this API is private, to avoid
455     /// revealing the internal, platform-specific encodings.
456     fn bytes(&self) -> &[u8] {
457         unsafe { mem::transmute(&self.inner) }
458     }
459 }
460
461 #[stable(feature = "box_from_os_str", since = "1.17.0")]
462 impl<'a> From<&'a OsStr> for Box<OsStr> {
463     fn from(s: &'a OsStr) -> Box<OsStr> {
464         unsafe { mem::transmute(s.inner.into_box()) }
465     }
466 }
467
468 #[stable(feature = "os_string_from_box", since = "1.17.0")]
469 impl<'a> From<Box<OsStr>> for OsString {
470     fn from(boxed: Box<OsStr>) -> OsString {
471         boxed.into_os_string()
472     }
473 }
474
475 #[stable(feature = "box_from_c_string", since = "1.17.0")]
476 impl Into<Box<OsStr>> for OsString {
477     fn into(self) -> Box<OsStr> {
478         self.into_boxed_os_str()
479     }
480 }
481
482 #[stable(feature = "box_default_extra", since = "1.17.0")]
483 impl Default for Box<OsStr> {
484     fn default() -> Box<OsStr> {
485         unsafe { mem::transmute(Slice::empty_box()) }
486     }
487 }
488
489 #[stable(feature = "osstring_default", since = "1.9.0")]
490 impl<'a> Default for &'a OsStr {
491     /// Creates an empty `OsStr`.
492     #[inline]
493     fn default() -> &'a OsStr {
494         OsStr::new("")
495     }
496 }
497
498 #[stable(feature = "rust1", since = "1.0.0")]
499 impl PartialEq for OsStr {
500     fn eq(&self, other: &OsStr) -> bool {
501         self.bytes().eq(other.bytes())
502     }
503 }
504
505 #[stable(feature = "rust1", since = "1.0.0")]
506 impl PartialEq<str> for OsStr {
507     fn eq(&self, other: &str) -> bool {
508         *self == *OsStr::new(other)
509     }
510 }
511
512 #[stable(feature = "rust1", since = "1.0.0")]
513 impl PartialEq<OsStr> for str {
514     fn eq(&self, other: &OsStr) -> bool {
515         *other == *OsStr::new(self)
516     }
517 }
518
519 #[stable(feature = "rust1", since = "1.0.0")]
520 impl Eq for OsStr {}
521
522 #[stable(feature = "rust1", since = "1.0.0")]
523 impl PartialOrd for OsStr {
524     #[inline]
525     fn partial_cmp(&self, other: &OsStr) -> Option<cmp::Ordering> {
526         self.bytes().partial_cmp(other.bytes())
527     }
528     #[inline]
529     fn lt(&self, other: &OsStr) -> bool { self.bytes().lt(other.bytes()) }
530     #[inline]
531     fn le(&self, other: &OsStr) -> bool { self.bytes().le(other.bytes()) }
532     #[inline]
533     fn gt(&self, other: &OsStr) -> bool { self.bytes().gt(other.bytes()) }
534     #[inline]
535     fn ge(&self, other: &OsStr) -> bool { self.bytes().ge(other.bytes()) }
536 }
537
538 #[stable(feature = "rust1", since = "1.0.0")]
539 impl PartialOrd<str> for OsStr {
540     #[inline]
541     fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
542         self.partial_cmp(OsStr::new(other))
543     }
544 }
545
546 // FIXME (#19470): cannot provide PartialOrd<OsStr> for str until we
547 // have more flexible coherence rules.
548
549 #[stable(feature = "rust1", since = "1.0.0")]
550 impl Ord for OsStr {
551     #[inline]
552     fn cmp(&self, other: &OsStr) -> cmp::Ordering { self.bytes().cmp(other.bytes()) }
553 }
554
555 macro_rules! impl_cmp {
556     ($lhs:ty, $rhs: ty) => {
557         #[stable(feature = "cmp_os_str", since = "1.8.0")]
558         impl<'a, 'b> PartialEq<$rhs> for $lhs {
559             #[inline]
560             fn eq(&self, other: &$rhs) -> bool { <OsStr as PartialEq>::eq(self, other) }
561         }
562
563         #[stable(feature = "cmp_os_str", since = "1.8.0")]
564         impl<'a, 'b> PartialEq<$lhs> for $rhs {
565             #[inline]
566             fn eq(&self, other: &$lhs) -> bool { <OsStr as PartialEq>::eq(self, other) }
567         }
568
569         #[stable(feature = "cmp_os_str", since = "1.8.0")]
570         impl<'a, 'b> PartialOrd<$rhs> for $lhs {
571             #[inline]
572             fn partial_cmp(&self, other: &$rhs) -> Option<cmp::Ordering> {
573                 <OsStr as PartialOrd>::partial_cmp(self, other)
574             }
575         }
576
577         #[stable(feature = "cmp_os_str", since = "1.8.0")]
578         impl<'a, 'b> PartialOrd<$lhs> for $rhs {
579             #[inline]
580             fn partial_cmp(&self, other: &$lhs) -> Option<cmp::Ordering> {
581                 <OsStr as PartialOrd>::partial_cmp(self, other)
582             }
583         }
584     }
585 }
586
587 impl_cmp!(OsString, OsStr);
588 impl_cmp!(OsString, &'a OsStr);
589 impl_cmp!(Cow<'a, OsStr>, OsStr);
590 impl_cmp!(Cow<'a, OsStr>, &'b OsStr);
591 impl_cmp!(Cow<'a, OsStr>, OsString);
592
593 #[stable(feature = "rust1", since = "1.0.0")]
594 impl Hash for OsStr {
595     #[inline]
596     fn hash<H: Hasher>(&self, state: &mut H) {
597         self.bytes().hash(state)
598     }
599 }
600
601 #[stable(feature = "rust1", since = "1.0.0")]
602 impl Debug for OsStr {
603     fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
604         self.inner.fmt(formatter)
605     }
606 }
607
608 #[stable(feature = "rust1", since = "1.0.0")]
609 impl Borrow<OsStr> for OsString {
610     fn borrow(&self) -> &OsStr { &self[..] }
611 }
612
613 #[stable(feature = "rust1", since = "1.0.0")]
614 impl ToOwned for OsStr {
615     type Owned = OsString;
616     fn to_owned(&self) -> OsString { self.to_os_string() }
617 }
618
619 #[stable(feature = "rust1", since = "1.0.0")]
620 impl AsRef<OsStr> for OsStr {
621     fn as_ref(&self) -> &OsStr {
622         self
623     }
624 }
625
626 #[stable(feature = "rust1", since = "1.0.0")]
627 impl AsRef<OsStr> for OsString {
628     fn as_ref(&self) -> &OsStr {
629         self
630     }
631 }
632
633 #[stable(feature = "rust1", since = "1.0.0")]
634 impl AsRef<OsStr> for str {
635     fn as_ref(&self) -> &OsStr {
636         OsStr::from_inner(Slice::from_str(self))
637     }
638 }
639
640 #[stable(feature = "rust1", since = "1.0.0")]
641 impl AsRef<OsStr> for String {
642     fn as_ref(&self) -> &OsStr {
643         (&**self).as_ref()
644     }
645 }
646
647 impl FromInner<Buf> for OsString {
648     fn from_inner(buf: Buf) -> OsString {
649         OsString { inner: buf }
650     }
651 }
652
653 impl IntoInner<Buf> for OsString {
654     fn into_inner(self) -> Buf {
655         self.inner
656     }
657 }
658
659 impl AsInner<Slice> for OsStr {
660     fn as_inner(&self) -> &Slice {
661         &self.inner
662     }
663 }
664
665 #[cfg(test)]
666 mod tests {
667     use super::*;
668     use sys_common::{AsInner, IntoInner};
669
670     #[test]
671     fn test_os_string_with_capacity() {
672         let os_string = OsString::with_capacity(0);
673         assert_eq!(0, os_string.inner.into_inner().capacity());
674
675         let os_string = OsString::with_capacity(10);
676         assert_eq!(10, os_string.inner.into_inner().capacity());
677
678         let mut os_string = OsString::with_capacity(0);
679         os_string.push("abc");
680         assert!(os_string.inner.into_inner().capacity() >= 3);
681     }
682
683     #[test]
684     fn test_os_string_clear() {
685         let mut os_string = OsString::from("abc");
686         assert_eq!(3, os_string.inner.as_inner().len());
687
688         os_string.clear();
689         assert_eq!(&os_string, "");
690         assert_eq!(0, os_string.inner.as_inner().len());
691     }
692
693     #[test]
694     fn test_os_string_capacity() {
695         let os_string = OsString::with_capacity(0);
696         assert_eq!(0, os_string.capacity());
697
698         let os_string = OsString::with_capacity(10);
699         assert_eq!(10, os_string.capacity());
700
701         let mut os_string = OsString::with_capacity(0);
702         os_string.push("abc");
703         assert!(os_string.capacity() >= 3);
704     }
705
706     #[test]
707     fn test_os_string_reserve() {
708         let mut os_string = OsString::new();
709         assert_eq!(os_string.capacity(), 0);
710
711         os_string.reserve(2);
712         assert!(os_string.capacity() >= 2);
713
714         for _ in 0..16 {
715             os_string.push("a");
716         }
717
718         assert!(os_string.capacity() >= 16);
719         os_string.reserve(16);
720         assert!(os_string.capacity() >= 32);
721
722         os_string.push("a");
723
724         os_string.reserve(16);
725         assert!(os_string.capacity() >= 33)
726     }
727
728     #[test]
729     fn test_os_string_reserve_exact() {
730         let mut os_string = OsString::new();
731         assert_eq!(os_string.capacity(), 0);
732
733         os_string.reserve_exact(2);
734         assert!(os_string.capacity() >= 2);
735
736         for _ in 0..16 {
737             os_string.push("a");
738         }
739
740         assert!(os_string.capacity() >= 16);
741         os_string.reserve_exact(16);
742         assert!(os_string.capacity() >= 32);
743
744         os_string.push("a");
745
746         os_string.reserve_exact(16);
747         assert!(os_string.capacity() >= 33)
748     }
749
750     #[test]
751     fn test_os_string_default() {
752         let os_string: OsString = Default::default();
753         assert_eq!("", &os_string);
754     }
755
756     #[test]
757     fn test_os_str_is_empty() {
758         let mut os_string = OsString::new();
759         assert!(os_string.is_empty());
760
761         os_string.push("abc");
762         assert!(!os_string.is_empty());
763
764         os_string.clear();
765         assert!(os_string.is_empty());
766     }
767
768     #[test]
769     fn test_os_str_len() {
770         let mut os_string = OsString::new();
771         assert_eq!(0, os_string.len());
772
773         os_string.push("abc");
774         assert_eq!(3, os_string.len());
775
776         os_string.clear();
777         assert_eq!(0, os_string.len());
778     }
779
780     #[test]
781     fn test_os_str_default() {
782         let os_str: &OsStr = Default::default();
783         assert_eq!("", os_str);
784     }
785
786     #[test]
787     fn into_boxed() {
788         let orig = "Hello, world!";
789         let os_str = OsStr::new(orig);
790         let boxed: Box<OsStr> = Box::from(os_str);
791         let os_string = os_str.to_owned().into_boxed_os_str().into_os_string();
792         assert_eq!(os_str, &*boxed);
793         assert_eq!(&*boxed, &*os_string);
794         assert_eq!(&*os_string, os_str);
795     }
796
797     #[test]
798     fn boxed_default() {
799         let boxed = <Box<OsStr>>::default();
800         assert!(boxed.is_empty());
801     }
802 }