Skip to content

Commit 88c1105

Browse files
committedJul 12, 2015
Auto merge of #26931 - reem:string-conversions, r=alexcrichton
Implements merged RFC 1152. Closes #26697.
2 parents 78547d2 + 69521af commit 88c1105

File tree

5 files changed

+39
-21
lines changed

5 files changed

+39
-21
lines changed
 

‎src/libcollections/str.rs

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ use core::result::Result;
6161
use core::str as core_str;
6262
use core::str::pattern::Pattern;
6363
use core::str::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher};
64+
use core::mem;
6465
use rustc_unicode::str::{UnicodeStr, Utf16Encoder};
6566

6667
use vec_deque::VecDeque;
@@ -69,6 +70,7 @@ use string::String;
6970
use rustc_unicode;
7071
use vec::Vec;
7172
use slice::SliceConcatExt;
73+
use boxed::Box;
7274

7375
pub use core::str::{FromStr, Utf8Error};
7476
pub use core::str::{Lines, LinesAny, CharRange};
@@ -82,10 +84,6 @@ pub use core::str::{from_utf8_unchecked, ParseBoolError};
8284
pub use rustc_unicode::str::{SplitWhitespace, Words, Graphemes, GraphemeIndices};
8385
pub use core::str::pattern;
8486

85-
/*
86-
Section: Creating a string
87-
*/
88-
8987
impl<S: Borrow<str>> SliceConcatExt<str> for [S] {
9088
type Output = String;
9189

@@ -134,10 +132,6 @@ impl<S: Borrow<str>> SliceConcatExt<str> for [S] {
134132
}
135133
}
136134

137-
/*
138-
Section: Iterators
139-
*/
140-
141135
// Helper functions used for Unicode normalization
142136
fn canonical_sort(comb: &mut [(char, u8)]) {
143137
let len = comb.len();
@@ -382,10 +376,6 @@ impl<'a> Iterator for Utf16Units<'a> {
382376
fn size_hint(&self) -> (usize, Option<usize>) { self.encoder.size_hint() }
383377
}
384378

385-
/*
386-
Section: Misc
387-
*/
388-
389379
// Return the initial codepoint accumulator for the first byte.
390380
// The first byte is special, only want bottom 5 bits for width 2, 4 bits
391381
// for width 3, and 3 bits for width 4
@@ -414,15 +404,6 @@ impl ToOwned for str {
414404
}
415405
}
416406

417-
/*
418-
Section: CowString
419-
*/
420-
421-
/*
422-
Section: Trait implementations
423-
*/
424-
425-
426407
/// Any string that can be represented as a slice.
427408
#[lang = "str"]
428409
#[cfg(not(test))]
@@ -1924,4 +1905,14 @@ impl str {
19241905
pub fn escape_unicode(&self) -> String {
19251906
self.chars().flat_map(|c| c.escape_unicode()).collect()
19261907
}
1908+
1909+
/// Converts the `Box<str>` into a `String` without copying or allocating.
1910+
#[unstable(feature = "box_str",
1911+
reason = "recently added, matches RFC")]
1912+
pub fn into_string(self: Box<str>) -> String {
1913+
unsafe {
1914+
let slice = mem::transmute::<Box<str>, Box<[u8]>>(self);
1915+
String::from_utf8_unchecked(slice.into_vec())
1916+
}
1917+
}
19271918
}

‎src/libcollections/string.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use borrow::{Cow, IntoCow};
2929
use range::RangeArgument;
3030
use str::{self, FromStr, Utf8Error, Chars};
3131
use vec::{DerefVec, Vec, as_vec};
32+
use boxed::Box;
3233

3334
/// A growable string stored as a UTF-8 encoded buffer.
3435
#[derive(Clone, PartialOrd, Eq, Ord)]
@@ -741,6 +742,16 @@ impl String {
741742
string: self_ptr,
742743
}
743744
}
745+
746+
/// Converts the string into `Box<str>`.
747+
///
748+
/// Note that this will drop any excess capacity.
749+
#[unstable(feature = "box_str",
750+
reason = "recently added, matches RFC")]
751+
pub fn into_boxed_slice(self) -> Box<str> {
752+
let slice = self.vec.into_boxed_slice();
753+
unsafe { mem::transmute::<Box<[u8]>, Box<str>>(slice) }
754+
}
744755
}
745756

746757
impl FromUtf8Error {

‎src/libcollectionstest/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#![feature(str_escape)]
4545
#![feature(str_match_indices)]
4646
#![feature(str_utf16)]
47+
#![feature(box_str)]
4748
#![feature(subslice_offset)]
4849
#![feature(test)]
4950
#![feature(unboxed_closures)]

‎src/libcollectionstest/str.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1746,6 +1746,14 @@ fn to_uppercase() {
17461746
assert_eq!("aéDžßfiᾀ".to_uppercase(), "AÉDŽSSFIἈΙ");
17471747
}
17481748

1749+
#[test]
1750+
fn test_into_string() {
1751+
// The only way to acquire a Box<str> in the first place is through a String, so just
1752+
// test that we can round-trip between Box<str> and String.
1753+
let string = String::from("Some text goes here");
1754+
assert_eq!(string.clone().into_boxed_slice().into_string(), string);
1755+
}
1756+
17491757
mod pattern {
17501758
use std::str::pattern::Pattern;
17511759
use std::str::pattern::{Searcher, ReverseSearcher};

‎src/libcollectionstest/string.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,13 @@ fn test_extend_ref() {
374374
assert_eq!(&a, "foobar");
375375
}
376376

377+
#[test]
378+
fn test_into_boxed_slice() {
379+
let xs = String::from("hello my name is bob");
380+
let ys = xs.into_boxed_slice();
381+
assert_eq!(&*ys, "hello my name is bob");
382+
}
383+
377384
#[bench]
378385
fn bench_with_capacity(b: &mut Bencher) {
379386
b.iter(|| {

0 commit comments

Comments
 (0)
Please sign in to comment.