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