Auto merge of #26931 - reem:string-conversions, r=alexcrichton
Implements merged RFC 1152. Closes #26697.
This commit is contained in:
commit
88c1105fc7
@ -61,6 +61,7 @@ use core::result::Result;
|
||||
use core::str as core_str;
|
||||
use core::str::pattern::Pattern;
|
||||
use core::str::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher};
|
||||
use core::mem;
|
||||
use rustc_unicode::str::{UnicodeStr, Utf16Encoder};
|
||||
|
||||
use vec_deque::VecDeque;
|
||||
@ -69,6 +70,7 @@ use string::String;
|
||||
use rustc_unicode;
|
||||
use vec::Vec;
|
||||
use slice::SliceConcatExt;
|
||||
use boxed::Box;
|
||||
|
||||
pub use core::str::{FromStr, Utf8Error};
|
||||
pub use core::str::{Lines, LinesAny, CharRange};
|
||||
@ -82,10 +84,6 @@ pub use core::str::{from_utf8_unchecked, ParseBoolError};
|
||||
pub use rustc_unicode::str::{SplitWhitespace, Words, Graphemes, GraphemeIndices};
|
||||
pub use core::str::pattern;
|
||||
|
||||
/*
|
||||
Section: Creating a string
|
||||
*/
|
||||
|
||||
impl<S: Borrow<str>> SliceConcatExt<str> for [S] {
|
||||
type Output = String;
|
||||
|
||||
@ -134,10 +132,6 @@ impl<S: Borrow<str>> SliceConcatExt<str> for [S] {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Section: Iterators
|
||||
*/
|
||||
|
||||
// Helper functions used for Unicode normalization
|
||||
fn canonical_sort(comb: &mut [(char, u8)]) {
|
||||
let len = comb.len();
|
||||
@ -382,10 +376,6 @@ impl<'a> Iterator for Utf16Units<'a> {
|
||||
fn size_hint(&self) -> (usize, Option<usize>) { self.encoder.size_hint() }
|
||||
}
|
||||
|
||||
/*
|
||||
Section: Misc
|
||||
*/
|
||||
|
||||
// Return the initial codepoint accumulator for the first byte.
|
||||
// The first byte is special, only want bottom 5 bits for width 2, 4 bits
|
||||
// for width 3, and 3 bits for width 4
|
||||
@ -414,15 +404,6 @@ impl ToOwned for str {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Section: CowString
|
||||
*/
|
||||
|
||||
/*
|
||||
Section: Trait implementations
|
||||
*/
|
||||
|
||||
|
||||
/// Any string that can be represented as a slice.
|
||||
#[lang = "str"]
|
||||
#[cfg(not(test))]
|
||||
@ -1924,4 +1905,14 @@ impl str {
|
||||
pub fn escape_unicode(&self) -> String {
|
||||
self.chars().flat_map(|c| c.escape_unicode()).collect()
|
||||
}
|
||||
|
||||
/// Converts the `Box<str>` into a `String` without copying or allocating.
|
||||
#[unstable(feature = "box_str",
|
||||
reason = "recently added, matches RFC")]
|
||||
pub fn into_string(self: Box<str>) -> String {
|
||||
unsafe {
|
||||
let slice = mem::transmute::<Box<str>, Box<[u8]>>(self);
|
||||
String::from_utf8_unchecked(slice.into_vec())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ use borrow::{Cow, IntoCow};
|
||||
use range::RangeArgument;
|
||||
use str::{self, FromStr, Utf8Error, Chars};
|
||||
use vec::{DerefVec, Vec, as_vec};
|
||||
use boxed::Box;
|
||||
|
||||
/// A growable string stored as a UTF-8 encoded buffer.
|
||||
#[derive(Clone, PartialOrd, Eq, Ord)]
|
||||
@ -741,6 +742,16 @@ impl String {
|
||||
string: self_ptr,
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts the string into `Box<str>`.
|
||||
///
|
||||
/// Note that this will drop any excess capacity.
|
||||
#[unstable(feature = "box_str",
|
||||
reason = "recently added, matches RFC")]
|
||||
pub fn into_boxed_slice(self) -> Box<str> {
|
||||
let slice = self.vec.into_boxed_slice();
|
||||
unsafe { mem::transmute::<Box<[u8]>, Box<str>>(slice) }
|
||||
}
|
||||
}
|
||||
|
||||
impl FromUtf8Error {
|
||||
|
@ -44,6 +44,7 @@
|
||||
#![feature(str_escape)]
|
||||
#![feature(str_match_indices)]
|
||||
#![feature(str_utf16)]
|
||||
#![feature(box_str)]
|
||||
#![feature(subslice_offset)]
|
||||
#![feature(test)]
|
||||
#![feature(unboxed_closures)]
|
||||
|
@ -1746,6 +1746,14 @@ fn to_uppercase() {
|
||||
assert_eq!("aéDžßfiᾀ".to_uppercase(), "AÉDŽSSFIἈΙ");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_into_string() {
|
||||
// The only way to acquire a Box<str> in the first place is through a String, so just
|
||||
// test that we can round-trip between Box<str> and String.
|
||||
let string = String::from("Some text goes here");
|
||||
assert_eq!(string.clone().into_boxed_slice().into_string(), string);
|
||||
}
|
||||
|
||||
mod pattern {
|
||||
use std::str::pattern::Pattern;
|
||||
use std::str::pattern::{Searcher, ReverseSearcher};
|
||||
|
@ -374,6 +374,13 @@ fn test_extend_ref() {
|
||||
assert_eq!(&a, "foobar");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_into_boxed_slice() {
|
||||
let xs = String::from("hello my name is bob");
|
||||
let ys = xs.into_boxed_slice();
|
||||
assert_eq!(&*ys, "hello my name is bob");
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_with_capacity(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
|
Loading…
x
Reference in New Issue
Block a user