Auto merge of #31608 - frewsxcv:osstring-simple-functions, r=alexcrichton
https://github.com/rust-lang/rust/issues/29453
This commit is contained in:
@@ -102,6 +102,58 @@ impl OsString {
|
|||||||
pub fn push<T: AsRef<OsStr>>(&mut self, s: T) {
|
pub fn push<T: AsRef<OsStr>>(&mut self, s: T) {
|
||||||
self.inner.push_slice(&s.as_ref().inner)
|
self.inner.push_slice(&s.as_ref().inner)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a new `OsString` with the given capacity. The string will be
|
||||||
|
/// able to hold exactly `capacity` bytes without reallocating. If
|
||||||
|
/// `capacity` is 0, the string will not allocate.
|
||||||
|
///
|
||||||
|
/// See main `OsString` documentation information about encoding.
|
||||||
|
#[unstable(feature = "osstring_simple_functions",
|
||||||
|
reason = "recently added", issue = "29453")]
|
||||||
|
pub fn with_capacity(capacity: usize) -> OsString {
|
||||||
|
OsString {
|
||||||
|
inner: Buf::with_capacity(capacity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Truncates the `OsString` to zero length.
|
||||||
|
#[unstable(feature = "osstring_simple_functions",
|
||||||
|
reason = "recently added", issue = "29453")]
|
||||||
|
pub fn clear(&mut self) {
|
||||||
|
self.inner.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the number of bytes this `OsString` can hold without
|
||||||
|
/// reallocating.
|
||||||
|
///
|
||||||
|
/// See `OsString` introduction for information about encoding.
|
||||||
|
#[unstable(feature = "osstring_simple_functions",
|
||||||
|
reason = "recently added", issue = "29453")]
|
||||||
|
pub fn capacity(&self) -> usize {
|
||||||
|
self.inner.capacity()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reserves capacity for at least `additional` more bytes to be inserted
|
||||||
|
/// in the given `OsString`. The collection may reserve more space to avoid
|
||||||
|
/// frequent reallocations.
|
||||||
|
#[unstable(feature = "osstring_simple_functions",
|
||||||
|
reason = "recently added", issue = "29453")]
|
||||||
|
pub fn reserve(&mut self, additional: usize) {
|
||||||
|
self.inner.reserve(additional)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reserves the minimum capacity for exactly `additional` more bytes to be
|
||||||
|
/// inserted in the given `OsString`. Does nothing if the capacity is
|
||||||
|
/// already sufficient.
|
||||||
|
///
|
||||||
|
/// Note that the allocator may give the collection more space than it
|
||||||
|
/// requests. Therefore capacity can not be relied upon to be precisely
|
||||||
|
/// minimal. Prefer reserve if future insertions are expected.
|
||||||
|
#[unstable(feature = "osstring_simple_functions",
|
||||||
|
reason = "recently added", issue = "29453")]
|
||||||
|
pub fn reserve_exact(&mut self, additional: usize) {
|
||||||
|
self.inner.reserve_exact(additional)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
@@ -277,6 +329,22 @@ impl OsStr {
|
|||||||
self.to_bytes().and_then(|b| CString::new(b).ok())
|
self.to_bytes().and_then(|b| CString::new(b).ok())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Checks whether the `OsStr` is empty.
|
||||||
|
#[unstable(feature = "osstring_simple_functions",
|
||||||
|
reason = "recently added", issue = "29453")]
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.inner.inner.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the number of bytes in this `OsStr`.
|
||||||
|
///
|
||||||
|
/// See `OsStr` introduction for information about encoding.
|
||||||
|
#[unstable(feature = "osstring_simple_functions",
|
||||||
|
reason = "recently added", issue = "29453")]
|
||||||
|
pub fn len(&self) -> usize {
|
||||||
|
self.inner.inner.len()
|
||||||
|
}
|
||||||
|
|
||||||
/// Gets the underlying byte representation.
|
/// Gets the underlying byte representation.
|
||||||
///
|
///
|
||||||
/// Note: it is *crucial* that this API is private, to avoid
|
/// Note: it is *crucial* that this API is private, to avoid
|
||||||
@@ -414,3 +482,113 @@ impl AsInner<Slice> for OsStr {
|
|||||||
&self.inner
|
&self.inner
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use sys_common::{AsInner, IntoInner};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_os_string_with_capacity() {
|
||||||
|
let os_string = OsString::with_capacity(0);
|
||||||
|
assert_eq!(0, os_string.inner.into_inner().capacity());
|
||||||
|
|
||||||
|
let os_string = OsString::with_capacity(10);
|
||||||
|
assert_eq!(10, os_string.inner.into_inner().capacity());
|
||||||
|
|
||||||
|
let mut os_string = OsString::with_capacity(0);
|
||||||
|
os_string.push("abc");
|
||||||
|
assert!(os_string.inner.into_inner().capacity() >= 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_os_string_clear() {
|
||||||
|
let mut os_string = OsString::from("abc");
|
||||||
|
assert_eq!(3, os_string.inner.as_inner().len());
|
||||||
|
|
||||||
|
os_string.clear();
|
||||||
|
assert_eq!(&os_string, "");
|
||||||
|
assert_eq!(0, os_string.inner.as_inner().len());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_os_string_capacity() {
|
||||||
|
let os_string = OsString::with_capacity(0);
|
||||||
|
assert_eq!(0, os_string.capacity());
|
||||||
|
|
||||||
|
let os_string = OsString::with_capacity(10);
|
||||||
|
assert_eq!(10, os_string.capacity());
|
||||||
|
|
||||||
|
let mut os_string = OsString::with_capacity(0);
|
||||||
|
os_string.push("abc");
|
||||||
|
assert!(os_string.capacity() >= 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_os_string_reserve() {
|
||||||
|
let mut os_string = OsString::new();
|
||||||
|
assert_eq!(os_string.capacity(), 0);
|
||||||
|
|
||||||
|
os_string.reserve(2);
|
||||||
|
assert!(os_string.capacity() >= 2);
|
||||||
|
|
||||||
|
for _ in 0..16 {
|
||||||
|
os_string.push("a");
|
||||||
|
}
|
||||||
|
|
||||||
|
assert!(os_string.capacity() >= 16);
|
||||||
|
os_string.reserve(16);
|
||||||
|
assert!(os_string.capacity() >= 32);
|
||||||
|
|
||||||
|
os_string.push("a");
|
||||||
|
|
||||||
|
os_string.reserve(16);
|
||||||
|
assert!(os_string.capacity() >= 33)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_os_string_reserve_exact() {
|
||||||
|
let mut os_string = OsString::new();
|
||||||
|
assert_eq!(os_string.capacity(), 0);
|
||||||
|
|
||||||
|
os_string.reserve_exact(2);
|
||||||
|
assert!(os_string.capacity() >= 2);
|
||||||
|
|
||||||
|
for _ in 0..16 {
|
||||||
|
os_string.push("a");
|
||||||
|
}
|
||||||
|
|
||||||
|
assert!(os_string.capacity() >= 16);
|
||||||
|
os_string.reserve_exact(16);
|
||||||
|
assert!(os_string.capacity() >= 32);
|
||||||
|
|
||||||
|
os_string.push("a");
|
||||||
|
|
||||||
|
os_string.reserve_exact(16);
|
||||||
|
assert!(os_string.capacity() >= 33)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_os_str_is_empty() {
|
||||||
|
let mut os_string = OsString::new();
|
||||||
|
assert!(os_string.is_empty());
|
||||||
|
|
||||||
|
os_string.push("abc");
|
||||||
|
assert!(!os_string.is_empty());
|
||||||
|
|
||||||
|
os_string.clear();
|
||||||
|
assert!(os_string.is_empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_os_str_len() {
|
||||||
|
let mut os_string = OsString::new();
|
||||||
|
assert_eq!(0, os_string.len());
|
||||||
|
|
||||||
|
os_string.push("abc");
|
||||||
|
assert_eq!(3, os_string.len());
|
||||||
|
|
||||||
|
os_string.clear();
|
||||||
|
assert_eq!(0, os_string.len());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -178,6 +178,10 @@ impl Wtf8Buf {
|
|||||||
Wtf8Buf { bytes: <[_]>::to_vec(str.as_bytes()) }
|
Wtf8Buf { bytes: <[_]>::to_vec(str.as_bytes()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn clear(&mut self) {
|
||||||
|
self.bytes.clear()
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a WTF-8 string from a potentially ill-formed UTF-16 slice of 16-bit code units.
|
/// Creates a WTF-8 string from a potentially ill-formed UTF-16 slice of 16-bit code units.
|
||||||
///
|
///
|
||||||
/// This is lossless: calling `.encode_wide()` on the resulting string
|
/// This is lossless: calling `.encode_wide()` on the resulting string
|
||||||
@@ -234,6 +238,11 @@ impl Wtf8Buf {
|
|||||||
self.bytes.reserve(additional)
|
self.bytes.reserve(additional)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn reserve_exact(&mut self, additional: usize) {
|
||||||
|
self.bytes.reserve_exact(additional)
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the number of bytes that this string buffer can hold without reallocating.
|
/// Returns the number of bytes that this string buffer can hold without reallocating.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn capacity(&self) -> usize {
|
pub fn capacity(&self) -> usize {
|
||||||
@@ -443,6 +452,11 @@ impl Wtf8 {
|
|||||||
self.bytes.len()
|
self.bytes.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.bytes.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the code point at `position` if it is in the ASCII range,
|
/// Returns the code point at `position` if it is in the ASCII range,
|
||||||
/// or `b'\xFF' otherwise.
|
/// or `b'\xFF' otherwise.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ use vec::Vec;
|
|||||||
use str;
|
use str;
|
||||||
use string::String;
|
use string::String;
|
||||||
use mem;
|
use mem;
|
||||||
|
use sys_common::{AsInner, IntoInner};
|
||||||
|
|
||||||
#[derive(Clone, Hash)]
|
#[derive(Clone, Hash)]
|
||||||
pub struct Buf {
|
pub struct Buf {
|
||||||
@@ -39,11 +40,51 @@ impl Debug for Buf {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl IntoInner<Vec<u8>> for Buf {
|
||||||
|
fn into_inner(self) -> Vec<u8> {
|
||||||
|
self.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsInner<[u8]> for Buf {
|
||||||
|
fn as_inner(&self) -> &[u8] {
|
||||||
|
&self.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Buf {
|
impl Buf {
|
||||||
pub fn from_string(s: String) -> Buf {
|
pub fn from_string(s: String) -> Buf {
|
||||||
Buf { inner: s.into_bytes() }
|
Buf { inner: s.into_bytes() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn with_capacity(capacity: usize) -> Buf {
|
||||||
|
Buf {
|
||||||
|
inner: Vec::with_capacity(capacity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn clear(&mut self) {
|
||||||
|
self.inner.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn capacity(&self) -> usize {
|
||||||
|
self.inner.capacity()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn reserve(&mut self, additional: usize) {
|
||||||
|
self.inner.reserve(additional)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn reserve_exact(&mut self, additional: usize) {
|
||||||
|
self.inner.reserve_exact(additional)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn as_slice(&self) -> &Slice {
|
pub fn as_slice(&self) -> &Slice {
|
||||||
unsafe { mem::transmute(&*self.inner) }
|
unsafe { mem::transmute(&*self.inner) }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,12 +18,25 @@ use string::String;
|
|||||||
use result::Result;
|
use result::Result;
|
||||||
use option::Option;
|
use option::Option;
|
||||||
use mem;
|
use mem;
|
||||||
|
use sys_common::{AsInner, IntoInner};
|
||||||
|
|
||||||
#[derive(Clone, Hash)]
|
#[derive(Clone, Hash)]
|
||||||
pub struct Buf {
|
pub struct Buf {
|
||||||
pub inner: Wtf8Buf
|
pub inner: Wtf8Buf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl IntoInner<Wtf8Buf> for Buf {
|
||||||
|
fn into_inner(self) -> Wtf8Buf {
|
||||||
|
self.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsInner<Wtf8> for Buf {
|
||||||
|
fn as_inner(&self) -> &Wtf8 {
|
||||||
|
&self.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Debug for Buf {
|
impl Debug for Buf {
|
||||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||||
self.as_slice().fmt(formatter)
|
self.as_slice().fmt(formatter)
|
||||||
@@ -41,6 +54,20 @@ impl Debug for Slice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Buf {
|
impl Buf {
|
||||||
|
pub fn with_capacity(capacity: usize) -> Buf {
|
||||||
|
Buf {
|
||||||
|
inner: Wtf8Buf::with_capacity(capacity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear(&mut self) {
|
||||||
|
self.inner.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn capacity(&self) -> usize {
|
||||||
|
self.inner.capacity()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn from_string(s: String) -> Buf {
|
pub fn from_string(s: String) -> Buf {
|
||||||
Buf { inner: Wtf8Buf::from_string(s) }
|
Buf { inner: Wtf8Buf::from_string(s) }
|
||||||
}
|
}
|
||||||
@@ -56,6 +83,14 @@ impl Buf {
|
|||||||
pub fn push_slice(&mut self, s: &Slice) {
|
pub fn push_slice(&mut self, s: &Slice) {
|
||||||
self.inner.push_wtf8(&s.inner)
|
self.inner.push_wtf8(&s.inner)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn reserve(&mut self, additional: usize) {
|
||||||
|
self.inner.reserve(additional)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reserve_exact(&mut self, additional: usize) {
|
||||||
|
self.inner.reserve_exact(additional)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Slice {
|
impl Slice {
|
||||||
|
|||||||
Reference in New Issue
Block a user