]> git.proxmox.com Git - rustc.git/blame - src/libstd/ffi/os_str.rs
New upstream version 1.17.0+dfsg1
[rustc.git] / src / libstd / ffi / os_str.rs
CommitLineData
85aaf69f
SL
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
9e0c209e 11use borrow::{Borrow, Cow};
85aaf69f
SL
12use fmt::{self, Debug};
13use mem;
85aaf69f
SL
14use ops;
15use cmp;
16use hash::{Hash, Hasher};
85aaf69f
SL
17
18use sys::os_str::{Buf, Slice};
19use sys_common::{AsInner, IntoInner, FromInner};
85aaf69f 20
9cc50fc6 21/// A type that can represent owned, mutable platform-native strings, but is
54a0048b 22/// cheaply inter-convertible with Rust strings.
9cc50fc6
SL
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///
32a655c1 34/// `OsString` and [`OsStr`] bridge this gap by simultaneously representing Rust
9cc50fc6
SL
35/// and platform-native string values, and in particular allowing a Rust string
36/// to be converted into an "OS" string with no cost.
32a655c1
SL
37///
38/// [`OsStr`]: struct.OsStr.html
85aaf69f 39#[derive(Clone)]
c34b1796 40#[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
41pub struct OsString {
42 inner: Buf
43}
44
32a655c1
SL
45/// Slices into OS strings (see [`OsString`]).
46///
47/// [`OsString`]: struct.OsString.html
c34b1796 48#[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
49pub struct OsStr {
50 inner: Slice
51}
52
53impl OsString {
85aaf69f 54 /// Constructs a new empty `OsString`.
32a655c1
SL
55 ///
56 /// # Examples
57 ///
58 /// ```
59 /// use std::ffi::OsString;
60 ///
61 /// let os_string = OsString::new();
62 /// ```
c34b1796 63 #[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
64 pub fn new() -> OsString {
65 OsString { inner: Buf::from_string(String::new()) }
66 }
67
32a655c1
SL
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 /// ```
c34b1796
AL
81 #[stable(feature = "rust1", since = "1.0.0")]
82 pub fn as_os_str(&self) -> &OsStr {
83 self
84 }
85
32a655c1 86 /// Converts the `OsString` into a [`String`] if it contains valid Unicode data.
85aaf69f
SL
87 ///
88 /// On failure, ownership of the original `OsString` is returned.
32a655c1
SL
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 /// ```
c34b1796 101 #[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
102 pub fn into_string(self) -> Result<String, OsString> {
103 self.inner.into_string().map_err(|buf| OsString { inner: buf} )
104 }
105
32a655c1
SL
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 /// ```
c34b1796
AL
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 }
7453a54e 123
54a0048b
SL
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.
7453a54e
SL
129 ///
130 /// See main `OsString` documentation information about encoding.
32a655c1
SL
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 /// ```
54a0048b 145 #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
7453a54e
SL
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.
32a655c1
SL
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 /// ```
54a0048b 165 #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
7453a54e
SL
166 pub fn clear(&mut self) {
167 self.inner.clear()
168 }
169
54a0048b 170 /// Returns the capacity this `OsString` can hold without reallocating.
7453a54e
SL
171 ///
172 /// See `OsString` introduction for information about encoding.
32a655c1
SL
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 /// ```
54a0048b 182 #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
7453a54e
SL
183 pub fn capacity(&self) -> usize {
184 self.inner.capacity()
185 }
186
54a0048b
SL
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")]
7453a54e
SL
192 pub fn reserve(&mut self, additional: usize) {
193 self.inner.reserve(additional)
194 }
195
54a0048b
SL
196 /// Reserves the minimum capacity for exactly `additional` more capacity to
197 /// be inserted in the given `OsString`. Does nothing if the capacity is
7453a54e
SL
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.
54a0048b 203 #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
7453a54e
SL
204 pub fn reserve_exact(&mut self, additional: usize) {
205 self.inner.reserve_exact(additional)
206 }
8bb4bdeb
XL
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 }
c34b1796
AL
219}
220
221#[stable(feature = "rust1", since = "1.0.0")]
222impl 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")]
229impl<'a, T: ?Sized + AsRef<OsStr>> From<&'a T> for OsString {
230 fn from(s: &'a T) -> OsString {
231 s.as_ref().to_os_string()
85aaf69f
SL
232 }
233}
234
c34b1796 235#[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
236impl ops::Index<ops::RangeFull> for OsString {
237 type Output = OsStr;
238
239 #[inline]
c34b1796 240 fn index(&self, _index: ops::RangeFull) -> &OsStr {
e9174d1e 241 OsStr::from_inner(self.inner.as_slice())
85aaf69f
SL
242 }
243}
244
c34b1796 245#[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
246impl ops::Deref for OsString {
247 type Target = OsStr;
248
249 #[inline]
250 fn deref(&self) -> &OsStr {
251 &self[..]
252 }
253}
254
54a0048b
SL
255#[stable(feature = "osstring_default", since = "1.9.0")]
256impl Default for OsString {
9e0c209e 257 /// Constructs an empty `OsString`.
54a0048b
SL
258 #[inline]
259 fn default() -> OsString {
260 OsString::new()
261 }
262}
263
c34b1796 264#[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
265impl Debug for OsString {
266 fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
267 fmt::Debug::fmt(&**self, formatter)
268 }
269}
270
c34b1796 271#[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
272impl PartialEq for OsString {
273 fn eq(&self, other: &OsString) -> bool {
274 &**self == &**other
275 }
276}
277
c34b1796 278#[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
279impl PartialEq<str> for OsString {
280 fn eq(&self, other: &str) -> bool {
281 &**self == other
282 }
283}
284
c34b1796 285#[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
286impl PartialEq<OsString> for str {
287 fn eq(&self, other: &OsString) -> bool {
288 &**other == self
289 }
290}
291
c34b1796 292#[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
293impl Eq for OsString {}
294
c34b1796 295#[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
296impl 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
c34b1796 311#[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
312impl PartialOrd<str> for OsString {
313 #[inline]
314 fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
315 (&**self).partial_cmp(other)
316 }
317}
318
c34b1796 319#[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
320impl Ord for OsString {
321 #[inline]
322 fn cmp(&self, other: &OsString) -> cmp::Ordering {
323 (&**self).cmp(&**other)
324 }
325}
326
85aaf69f
SL
327#[stable(feature = "rust1", since = "1.0.0")]
328impl Hash for OsString {
329 #[inline]
330 fn hash<H: Hasher>(&self, state: &mut H) {
331 (&**self).hash(state)
332 }
333}
334
335impl OsStr {
9346a6ac 336 /// Coerces into an `OsStr` slice.
9e0c209e
SL
337 ///
338 /// # Examples
339 ///
340 /// ```
341 /// use std::ffi::OsStr;
342 ///
343 /// let os_str = OsStr::new("foo");
344 /// ```
c34b1796
AL
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
e9174d1e
SL
350 fn from_inner(inner: &Slice) -> &OsStr {
351 unsafe { mem::transmute(inner) }
352 }
353
32a655c1 354 /// Yields a [`&str`] slice if the `OsStr` is valid Unicode.
85aaf69f
SL
355 ///
356 /// This conversion may entail doing a check for UTF-8 validity.
32a655c1
SL
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 /// ```
c34b1796 368 #[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
369 pub fn to_str(&self) -> Option<&str> {
370 self.inner.to_str()
371 }
372
32a655c1 373 /// Converts an `OsStr` to a [`Cow`]`<`[`str`]`>`.
85aaf69f
SL
374 ///
375 /// Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER.
32a655c1
SL
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�"`.
c34b1796
AL
393 #[stable(feature = "rust1", since = "1.0.0")]
394 pub fn to_string_lossy(&self) -> Cow<str> {
85aaf69f
SL
395 self.inner.to_string_lossy()
396 }
397
32a655c1
SL
398 /// Copies the slice into an owned [`OsString`].
399 ///
400 /// [`OsString`]: struct.OsString.html
c34b1796 401 #[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
402 pub fn to_os_string(&self) -> OsString {
403 OsString { inner: self.inner.to_owned() }
404 }
405
7453a54e 406 /// Checks whether the `OsStr` is empty.
9e0c209e
SL
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 /// ```
54a0048b 419 #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
7453a54e
SL
420 pub fn is_empty(&self) -> bool {
421 self.inner.inner.is_empty()
422 }
423
54a0048b
SL
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
32a655c1 429 /// other methods like [`OsString::with_capacity`] to avoid reallocations.
7453a54e 430 ///
54a0048b 431 /// See `OsStr` introduction for more information about encoding.
9e0c209e 432 ///
32a655c1
SL
433 /// [`OsString::with_capacity`]: struct.OsString.html#method.with_capacity
434 ///
9e0c209e
SL
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 /// ```
54a0048b 446 #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
7453a54e
SL
447 pub fn len(&self) -> usize {
448 self.inner.inner.len()
449 }
450
9346a6ac 451 /// Gets the underlying byte representation.
85aaf69f
SL
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
8bb4bdeb
XL
460#[stable(feature = "box_from_os_str", since = "1.17.0")]
461impl<'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")]
468impl Default for Box<OsStr> {
469 fn default() -> Box<OsStr> {
470 unsafe { mem::transmute(Slice::empty_box()) }
471 }
472}
473
54a0048b
SL
474#[stable(feature = "osstring_default", since = "1.9.0")]
475impl<'a> Default for &'a OsStr {
9e0c209e 476 /// Creates an empty `OsStr`.
54a0048b
SL
477 #[inline]
478 fn default() -> &'a OsStr {
479 OsStr::new("")
480 }
481}
482
c34b1796 483#[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
484impl PartialEq for OsStr {
485 fn eq(&self, other: &OsStr) -> bool {
486 self.bytes().eq(other.bytes())
487 }
488}
489
c34b1796 490#[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
491impl PartialEq<str> for OsStr {
492 fn eq(&self, other: &str) -> bool {
c34b1796 493 *self == *OsStr::new(other)
85aaf69f
SL
494 }
495}
496
c34b1796 497#[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
498impl PartialEq<OsStr> for str {
499 fn eq(&self, other: &OsStr) -> bool {
c34b1796 500 *other == *OsStr::new(self)
85aaf69f
SL
501 }
502}
503
c34b1796 504#[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
505impl Eq for OsStr {}
506
c34b1796 507#[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
508impl 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
c34b1796 523#[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
524impl PartialOrd<str> for OsStr {
525 #[inline]
526 fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
c34b1796 527 self.partial_cmp(OsStr::new(other))
85aaf69f
SL
528 }
529}
530
531// FIXME (#19470): cannot provide PartialOrd<OsStr> for str until we
532// have more flexible coherence rules.
533
c34b1796 534#[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
535impl Ord for OsStr {
536 #[inline]
537 fn cmp(&self, other: &OsStr) -> cmp::Ordering { self.bytes().cmp(other.bytes()) }
538}
539
7453a54e
SL
540macro_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
572impl_cmp!(OsString, OsStr);
573impl_cmp!(OsString, &'a OsStr);
574impl_cmp!(Cow<'a, OsStr>, OsStr);
575impl_cmp!(Cow<'a, OsStr>, &'b OsStr);
576impl_cmp!(Cow<'a, OsStr>, OsString);
577
85aaf69f
SL
578#[stable(feature = "rust1", since = "1.0.0")]
579impl Hash for OsStr {
580 #[inline]
581 fn hash<H: Hasher>(&self, state: &mut H) {
582 self.bytes().hash(state)
583 }
584}
585
c34b1796 586#[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
587impl Debug for OsStr {
588 fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
589 self.inner.fmt(formatter)
590 }
591}
592
c34b1796 593#[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
594impl Borrow<OsStr> for OsString {
595 fn borrow(&self) -> &OsStr { &self[..] }
596}
597
c34b1796 598#[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
599impl ToOwned for OsStr {
600 type Owned = OsString;
601 fn to_owned(&self) -> OsString { self.to_os_string() }
602}
603
c34b1796
AL
604#[stable(feature = "rust1", since = "1.0.0")]
605impl AsRef<OsStr> for OsStr {
606 fn as_ref(&self) -> &OsStr {
607 self
85aaf69f
SL
608 }
609}
610
c34b1796
AL
611#[stable(feature = "rust1", since = "1.0.0")]
612impl AsRef<OsStr> for OsString {
613 fn as_ref(&self) -> &OsStr {
614 self
615 }
616}
617
618#[stable(feature = "rust1", since = "1.0.0")]
619impl AsRef<OsStr> for str {
620 fn as_ref(&self) -> &OsStr {
e9174d1e 621 OsStr::from_inner(Slice::from_str(self))
c34b1796
AL
622 }
623}
624
625#[stable(feature = "rust1", since = "1.0.0")]
626impl AsRef<OsStr> for String {
627 fn as_ref(&self) -> &OsStr {
e9174d1e 628 (&**self).as_ref()
c34b1796
AL
629 }
630}
631
85aaf69f
SL
632impl FromInner<Buf> for OsString {
633 fn from_inner(buf: Buf) -> OsString {
634 OsString { inner: buf }
635 }
636}
637
638impl IntoInner<Buf> for OsString {
639 fn into_inner(self) -> Buf {
640 self.inner
641 }
642}
643
644impl AsInner<Slice> for OsStr {
645 fn as_inner(&self) -> &Slice {
646 &self.inner
647 }
648}
7453a54e
SL
649
650#[cfg(test)]
651mod 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
54a0048b
SL
735 #[test]
736 fn test_os_string_default() {
737 let os_string: OsString = Default::default();
738 assert_eq!("", &os_string);
739 }
740
7453a54e
SL
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 }
54a0048b
SL
764
765 #[test]
766 fn test_os_str_default() {
767 let os_str: &OsStr = Default::default();
768 assert_eq!("", os_str);
769 }
8bb4bdeb
XL
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 }
7453a54e 788}