Skip to content

Commit 4f3d588

Browse files
committed
Auto merge of #31608 - frewsxcv:osstring-simple-functions, r=alexcrichton
#29453
2 parents d3ffad7 + 8c3655b commit 4f3d588

File tree

4 files changed

+255
-0
lines changed

4 files changed

+255
-0
lines changed

src/libstd/ffi/os_str.rs

+178
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,58 @@ impl OsString {
102102
pub fn push<T: AsRef<OsStr>>(&mut self, s: T) {
103103
self.inner.push_slice(&s.as_ref().inner)
104104
}
105+
106+
/// Creates a new `OsString` with the given capacity. The string will be
107+
/// able to hold exactly `capacity` bytes without reallocating. If
108+
/// `capacity` is 0, the string will not allocate.
109+
///
110+
/// See main `OsString` documentation information about encoding.
111+
#[unstable(feature = "osstring_simple_functions",
112+
reason = "recently added", issue = "29453")]
113+
pub fn with_capacity(capacity: usize) -> OsString {
114+
OsString {
115+
inner: Buf::with_capacity(capacity)
116+
}
117+
}
118+
119+
/// Truncates the `OsString` to zero length.
120+
#[unstable(feature = "osstring_simple_functions",
121+
reason = "recently added", issue = "29453")]
122+
pub fn clear(&mut self) {
123+
self.inner.clear()
124+
}
125+
126+
/// Returns the number of bytes this `OsString` can hold without
127+
/// reallocating.
128+
///
129+
/// See `OsString` introduction for information about encoding.
130+
#[unstable(feature = "osstring_simple_functions",
131+
reason = "recently added", issue = "29453")]
132+
pub fn capacity(&self) -> usize {
133+
self.inner.capacity()
134+
}
135+
136+
/// Reserves capacity for at least `additional` more bytes to be inserted
137+
/// in the given `OsString`. The collection may reserve more space to avoid
138+
/// frequent reallocations.
139+
#[unstable(feature = "osstring_simple_functions",
140+
reason = "recently added", issue = "29453")]
141+
pub fn reserve(&mut self, additional: usize) {
142+
self.inner.reserve(additional)
143+
}
144+
145+
/// Reserves the minimum capacity for exactly `additional` more bytes to be
146+
/// inserted in the given `OsString`. Does nothing if the capacity is
147+
/// already sufficient.
148+
///
149+
/// Note that the allocator may give the collection more space than it
150+
/// requests. Therefore capacity can not be relied upon to be precisely
151+
/// minimal. Prefer reserve if future insertions are expected.
152+
#[unstable(feature = "osstring_simple_functions",
153+
reason = "recently added", issue = "29453")]
154+
pub fn reserve_exact(&mut self, additional: usize) {
155+
self.inner.reserve_exact(additional)
156+
}
105157
}
106158

107159
#[stable(feature = "rust1", since = "1.0.0")]
@@ -277,6 +329,22 @@ impl OsStr {
277329
self.to_bytes().and_then(|b| CString::new(b).ok())
278330
}
279331

332+
/// Checks whether the `OsStr` is empty.
333+
#[unstable(feature = "osstring_simple_functions",
334+
reason = "recently added", issue = "29453")]
335+
pub fn is_empty(&self) -> bool {
336+
self.inner.inner.is_empty()
337+
}
338+
339+
/// Returns the number of bytes in this `OsStr`.
340+
///
341+
/// See `OsStr` introduction for information about encoding.
342+
#[unstable(feature = "osstring_simple_functions",
343+
reason = "recently added", issue = "29453")]
344+
pub fn len(&self) -> usize {
345+
self.inner.inner.len()
346+
}
347+
280348
/// Gets the underlying byte representation.
281349
///
282350
/// Note: it is *crucial* that this API is private, to avoid
@@ -414,3 +482,113 @@ impl AsInner<Slice> for OsStr {
414482
&self.inner
415483
}
416484
}
485+
486+
#[cfg(test)]
487+
mod tests {
488+
use super::*;
489+
use sys_common::{AsInner, IntoInner};
490+
491+
#[test]
492+
fn test_os_string_with_capacity() {
493+
let os_string = OsString::with_capacity(0);
494+
assert_eq!(0, os_string.inner.into_inner().capacity());
495+
496+
let os_string = OsString::with_capacity(10);
497+
assert_eq!(10, os_string.inner.into_inner().capacity());
498+
499+
let mut os_string = OsString::with_capacity(0);
500+
os_string.push("abc");
501+
assert!(os_string.inner.into_inner().capacity() >= 3);
502+
}
503+
504+
#[test]
505+
fn test_os_string_clear() {
506+
let mut os_string = OsString::from("abc");
507+
assert_eq!(3, os_string.inner.as_inner().len());
508+
509+
os_string.clear();
510+
assert_eq!(&os_string, "");
511+
assert_eq!(0, os_string.inner.as_inner().len());
512+
}
513+
514+
#[test]
515+
fn test_os_string_capacity() {
516+
let os_string = OsString::with_capacity(0);
517+
assert_eq!(0, os_string.capacity());
518+
519+
let os_string = OsString::with_capacity(10);
520+
assert_eq!(10, os_string.capacity());
521+
522+
let mut os_string = OsString::with_capacity(0);
523+
os_string.push("abc");
524+
assert!(os_string.capacity() >= 3);
525+
}
526+
527+
#[test]
528+
fn test_os_string_reserve() {
529+
let mut os_string = OsString::new();
530+
assert_eq!(os_string.capacity(), 0);
531+
532+
os_string.reserve(2);
533+
assert!(os_string.capacity() >= 2);
534+
535+
for _ in 0..16 {
536+
os_string.push("a");
537+
}
538+
539+
assert!(os_string.capacity() >= 16);
540+
os_string.reserve(16);
541+
assert!(os_string.capacity() >= 32);
542+
543+
os_string.push("a");
544+
545+
os_string.reserve(16);
546+
assert!(os_string.capacity() >= 33)
547+
}
548+
549+
#[test]
550+
fn test_os_string_reserve_exact() {
551+
let mut os_string = OsString::new();
552+
assert_eq!(os_string.capacity(), 0);
553+
554+
os_string.reserve_exact(2);
555+
assert!(os_string.capacity() >= 2);
556+
557+
for _ in 0..16 {
558+
os_string.push("a");
559+
}
560+
561+
assert!(os_string.capacity() >= 16);
562+
os_string.reserve_exact(16);
563+
assert!(os_string.capacity() >= 32);
564+
565+
os_string.push("a");
566+
567+
os_string.reserve_exact(16);
568+
assert!(os_string.capacity() >= 33)
569+
}
570+
571+
#[test]
572+
fn test_os_str_is_empty() {
573+
let mut os_string = OsString::new();
574+
assert!(os_string.is_empty());
575+
576+
os_string.push("abc");
577+
assert!(!os_string.is_empty());
578+
579+
os_string.clear();
580+
assert!(os_string.is_empty());
581+
}
582+
583+
#[test]
584+
fn test_os_str_len() {
585+
let mut os_string = OsString::new();
586+
assert_eq!(0, os_string.len());
587+
588+
os_string.push("abc");
589+
assert_eq!(3, os_string.len());
590+
591+
os_string.clear();
592+
assert_eq!(0, os_string.len());
593+
}
594+
}

src/libstd/sys/common/wtf8.rs

+14
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,10 @@ impl Wtf8Buf {
178178
Wtf8Buf { bytes: <[_]>::to_vec(str.as_bytes()) }
179179
}
180180

181+
pub fn clear(&mut self) {
182+
self.bytes.clear()
183+
}
184+
181185
/// Creates a WTF-8 string from a potentially ill-formed UTF-16 slice of 16-bit code units.
182186
///
183187
/// This is lossless: calling `.encode_wide()` on the resulting string
@@ -234,6 +238,11 @@ impl Wtf8Buf {
234238
self.bytes.reserve(additional)
235239
}
236240

241+
#[inline]
242+
pub fn reserve_exact(&mut self, additional: usize) {
243+
self.bytes.reserve_exact(additional)
244+
}
245+
237246
/// Returns the number of bytes that this string buffer can hold without reallocating.
238247
#[inline]
239248
pub fn capacity(&self) -> usize {
@@ -443,6 +452,11 @@ impl Wtf8 {
443452
self.bytes.len()
444453
}
445454

455+
#[inline]
456+
pub fn is_empty(&self) -> bool {
457+
self.bytes.is_empty()
458+
}
459+
446460
/// Returns the code point at `position` if it is in the ASCII range,
447461
/// or `b'\xFF' otherwise.
448462
///

src/libstd/sys/unix/os_str.rs

+41
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use vec::Vec;
1717
use str;
1818
use string::String;
1919
use mem;
20+
use sys_common::{AsInner, IntoInner};
2021

2122
#[derive(Clone, Hash)]
2223
pub struct Buf {
@@ -39,11 +40,51 @@ impl Debug for Buf {
3940
}
4041
}
4142

43+
impl IntoInner<Vec<u8>> for Buf {
44+
fn into_inner(self) -> Vec<u8> {
45+
self.inner
46+
}
47+
}
48+
49+
impl AsInner<[u8]> for Buf {
50+
fn as_inner(&self) -> &[u8] {
51+
&self.inner
52+
}
53+
}
54+
55+
4256
impl Buf {
4357
pub fn from_string(s: String) -> Buf {
4458
Buf { inner: s.into_bytes() }
4559
}
4660

61+
#[inline]
62+
pub fn with_capacity(capacity: usize) -> Buf {
63+
Buf {
64+
inner: Vec::with_capacity(capacity)
65+
}
66+
}
67+
68+
#[inline]
69+
pub fn clear(&mut self) {
70+
self.inner.clear()
71+
}
72+
73+
#[inline]
74+
pub fn capacity(&self) -> usize {
75+
self.inner.capacity()
76+
}
77+
78+
#[inline]
79+
pub fn reserve(&mut self, additional: usize) {
80+
self.inner.reserve(additional)
81+
}
82+
83+
#[inline]
84+
pub fn reserve_exact(&mut self, additional: usize) {
85+
self.inner.reserve_exact(additional)
86+
}
87+
4788
pub fn as_slice(&self) -> &Slice {
4889
unsafe { mem::transmute(&*self.inner) }
4990
}

src/libstd/sys/windows/os_str.rs

+22
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,20 @@ impl Debug for Slice {
4141
}
4242

4343
impl Buf {
44+
pub fn with_capacity(capacity: usize) -> Buf {
45+
Buf {
46+
inner: Wtf8Buf::with_capacity(capacity)
47+
}
48+
}
49+
50+
pub fn clear(&mut self) {
51+
self.inner.clear()
52+
}
53+
54+
pub fn capacity(&self) -> usize {
55+
self.inner.capacity()
56+
}
57+
4458
pub fn from_string(s: String) -> Buf {
4559
Buf { inner: Wtf8Buf::from_string(s) }
4660
}
@@ -56,6 +70,14 @@ impl Buf {
5670
pub fn push_slice(&mut self, s: &Slice) {
5771
self.inner.push_wtf8(&s.inner)
5872
}
73+
74+
pub fn reserve(&mut self, additional: usize) {
75+
self.inner.reserve(additional)
76+
}
77+
78+
pub fn reserve_exact(&mut self, additional: usize) {
79+
self.inner.reserve_exact(additional)
80+
}
5981
}
6082

6183
impl Slice {

0 commit comments

Comments
 (0)