Skip to content

Commit 24175e8

Browse files
committed
Auto merge of #38056 - clarcharr:master, r=alexcrichton
Add String::split_off. This seems to match up with the latest version of the collection reform, and seems useful enough to add. First pull request!
2 parents 08faff4 + cbf734f commit 24175e8

File tree

3 files changed

+73
-0
lines changed

3 files changed

+73
-0
lines changed

src/libcollections/string.rs

+33
Original file line numberDiff line numberDiff line change
@@ -1260,6 +1260,39 @@ impl String {
12601260
self.len() == 0
12611261
}
12621262

1263+
/// Divide one string into two at an index.
1264+
///
1265+
/// The argument, `mid`, should be a byte offset from the start of the string. It must also
1266+
/// be on the boundary of a UTF-8 code point.
1267+
///
1268+
/// The two strings returned go from the start of the string to `mid`, and from `mid` to the end
1269+
/// of the string.
1270+
///
1271+
/// # Panics
1272+
///
1273+
/// Panics if `mid` is not on a `UTF-8` code point boundary, or if it is beyond the last
1274+
/// code point of the string.
1275+
///
1276+
/// # Examples
1277+
///
1278+
/// ```
1279+
/// # #![feature(string_split_off)]
1280+
/// # fn main() {
1281+
/// let mut hello = String::from("Hello, World!");
1282+
/// let world = hello.split_off(7);
1283+
/// assert_eq!(hello, "Hello, ");
1284+
/// assert_eq!(world, "World!");
1285+
/// # }
1286+
/// ```
1287+
#[inline]
1288+
#[unstable(feature = "string_split_off", issue = "38080")]
1289+
pub fn split_off(&mut self, mid: usize) -> String {
1290+
assert!(self.is_char_boundary(mid));
1291+
assert!(mid <= self.len());
1292+
let other = self.vec.split_off(mid);
1293+
unsafe { String::from_utf8_unchecked(other) }
1294+
}
1295+
12631296
/// Truncates this `String`, removing all contents.
12641297
///
12651298
/// While this means the `String` will have a length of zero, it does not

src/libcollectionstest/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#![feature(step_by)]
2626
#![feature(str_escape)]
2727
#![feature(str_replacen)]
28+
#![feature(string_split_off)]
2829
#![feature(test)]
2930
#![feature(unboxed_closures)]
3031
#![feature(unicode)]

src/libcollectionstest/string.rs

+39
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,45 @@ fn test_pop() {
231231
assert_eq!(data, "ประเทศไทย中");
232232
}
233233

234+
#[test]
235+
fn test_split_off_empty() {
236+
let orig = "Hello, world!";
237+
let mut split = String::from(orig);
238+
let empty: String = split.split_off(orig.len());
239+
assert!(empty.is_empty());
240+
}
241+
242+
#[test]
243+
#[should_panic]
244+
fn test_split_off_past_end() {
245+
let orig = "Hello, world!";
246+
let mut split = String::from(orig);
247+
split.split_off(orig.len() + 1);
248+
}
249+
250+
#[test]
251+
#[should_panic]
252+
fn test_split_off_mid_char() {
253+
let mut orig = String::from("山");
254+
orig.split_off(1);
255+
}
256+
257+
#[test]
258+
fn test_split_off_ascii() {
259+
let mut ab = String::from("ABCD");
260+
let cd = ab.split_off(2);
261+
assert_eq!(ab, "AB");
262+
assert_eq!(cd, "CD");
263+
}
264+
265+
#[test]
266+
fn test_split_off_unicode() {
267+
let mut nihon = String::from("日本語");
268+
let go = nihon.split_off("日本".len());
269+
assert_eq!(nihon, "日本");
270+
assert_eq!(go, "語");
271+
}
272+
234273
#[test]
235274
fn test_str_truncate() {
236275
let mut s = String::from("12345");

0 commit comments

Comments
 (0)