Auto merge of #26931 - reem:string-conversions, r=alexcrichton
Implements merged RFC 1152. Closes #26697.
This commit is contained in:
@@ -61,6 +61,7 @@ use core::result::Result;
|
|||||||
use core::str as core_str;
|
use core::str as core_str;
|
||||||
use core::str::pattern::Pattern;
|
use core::str::pattern::Pattern;
|
||||||
use core::str::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher};
|
use core::str::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher};
|
||||||
|
use core::mem;
|
||||||
use rustc_unicode::str::{UnicodeStr, Utf16Encoder};
|
use rustc_unicode::str::{UnicodeStr, Utf16Encoder};
|
||||||
|
|
||||||
use vec_deque::VecDeque;
|
use vec_deque::VecDeque;
|
||||||
@@ -69,6 +70,7 @@ use string::String;
|
|||||||
use rustc_unicode;
|
use rustc_unicode;
|
||||||
use vec::Vec;
|
use vec::Vec;
|
||||||
use slice::SliceConcatExt;
|
use slice::SliceConcatExt;
|
||||||
|
use boxed::Box;
|
||||||
|
|
||||||
pub use core::str::{FromStr, Utf8Error};
|
pub use core::str::{FromStr, Utf8Error};
|
||||||
pub use core::str::{Lines, LinesAny, CharRange};
|
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 rustc_unicode::str::{SplitWhitespace, Words, Graphemes, GraphemeIndices};
|
||||||
pub use core::str::pattern;
|
pub use core::str::pattern;
|
||||||
|
|
||||||
/*
|
|
||||||
Section: Creating a string
|
|
||||||
*/
|
|
||||||
|
|
||||||
impl<S: Borrow<str>> SliceConcatExt<str> for [S] {
|
impl<S: Borrow<str>> SliceConcatExt<str> for [S] {
|
||||||
type Output = String;
|
type Output = String;
|
||||||
|
|
||||||
@@ -134,10 +132,6 @@ impl<S: Borrow<str>> SliceConcatExt<str> for [S] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Section: Iterators
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Helper functions used for Unicode normalization
|
// Helper functions used for Unicode normalization
|
||||||
fn canonical_sort(comb: &mut [(char, u8)]) {
|
fn canonical_sort(comb: &mut [(char, u8)]) {
|
||||||
let len = comb.len();
|
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() }
|
fn size_hint(&self) -> (usize, Option<usize>) { self.encoder.size_hint() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Section: Misc
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Return the initial codepoint accumulator for the first byte.
|
// Return the initial codepoint accumulator for the first byte.
|
||||||
// The first byte is special, only want bottom 5 bits for width 2, 4 bits
|
// The first byte is special, only want bottom 5 bits for width 2, 4 bits
|
||||||
// for width 3, and 3 bits for width 4
|
// 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.
|
/// Any string that can be represented as a slice.
|
||||||
#[lang = "str"]
|
#[lang = "str"]
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
@@ -1924,4 +1905,14 @@ impl str {
|
|||||||
pub fn escape_unicode(&self) -> String {
|
pub fn escape_unicode(&self) -> String {
|
||||||
self.chars().flat_map(|c| c.escape_unicode()).collect()
|
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 range::RangeArgument;
|
||||||
use str::{self, FromStr, Utf8Error, Chars};
|
use str::{self, FromStr, Utf8Error, Chars};
|
||||||
use vec::{DerefVec, Vec, as_vec};
|
use vec::{DerefVec, Vec, as_vec};
|
||||||
|
use boxed::Box;
|
||||||
|
|
||||||
/// A growable string stored as a UTF-8 encoded buffer.
|
/// A growable string stored as a UTF-8 encoded buffer.
|
||||||
#[derive(Clone, PartialOrd, Eq, Ord)]
|
#[derive(Clone, PartialOrd, Eq, Ord)]
|
||||||
@@ -741,6 +742,16 @@ impl String {
|
|||||||
string: self_ptr,
|
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 {
|
impl FromUtf8Error {
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
#![feature(str_escape)]
|
#![feature(str_escape)]
|
||||||
#![feature(str_match_indices)]
|
#![feature(str_match_indices)]
|
||||||
#![feature(str_utf16)]
|
#![feature(str_utf16)]
|
||||||
|
#![feature(box_str)]
|
||||||
#![feature(subslice_offset)]
|
#![feature(subslice_offset)]
|
||||||
#![feature(test)]
|
#![feature(test)]
|
||||||
#![feature(unboxed_closures)]
|
#![feature(unboxed_closures)]
|
||||||
|
|||||||
@@ -1746,6 +1746,14 @@ fn to_uppercase() {
|
|||||||
assert_eq!("aéDžßfiᾀ".to_uppercase(), "AÉDŽSSFIἈΙ");
|
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 {
|
mod pattern {
|
||||||
use std::str::pattern::Pattern;
|
use std::str::pattern::Pattern;
|
||||||
use std::str::pattern::{Searcher, ReverseSearcher};
|
use std::str::pattern::{Searcher, ReverseSearcher};
|
||||||
|
|||||||
@@ -374,6 +374,13 @@ fn test_extend_ref() {
|
|||||||
assert_eq!(&a, "foobar");
|
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]
|
#[bench]
|
||||||
fn bench_with_capacity(b: &mut Bencher) {
|
fn bench_with_capacity(b: &mut Bencher) {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
|
|||||||
Reference in New Issue
Block a user