Skip to content

Commit db71ff3

Browse files
committed
libcore: Add some methods to make working with string slices easier
1 parent 80429dd commit db71ff3

File tree

1 file changed

+56
-0
lines changed

1 file changed

+56
-0
lines changed

src/libcore/str.rs

+56
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export
3232
push_char,
3333
pop_char,
3434
shift_char,
35+
view_shift_char,
3536
unshift_char,
3637
trim_left,
3738
trim_right,
@@ -43,6 +44,7 @@ export
4344
chars,
4445
substr,
4546
slice,
47+
view,
4648
split, splitn, split_nonempty,
4749
split_char, splitn_char, split_char_nonempty,
4850
split_str, split_str_nonempty,
@@ -338,6 +340,22 @@ fn shift_char(&s: ~str) -> char {
338340
return ch;
339341
}
340342

343+
/**
344+
* Removes the first character from a string slice and returns it. This does
345+
* not allocate a new string; instead, it mutates a slice to point one
346+
* character beyond the character that was shifted.
347+
*
348+
* # Failure
349+
*
350+
* If the string does not contain any characters
351+
*/
352+
#[inline]
353+
fn view_shift_char(s: &a/str) -> (char, &a/str) {
354+
let {ch, next} = char_range_at(s, 0u);
355+
let next_s = unsafe { unsafe::view_bytes(s, next, len(s)) };
356+
return (ch, next_s);
357+
}
358+
341359
/// Prepend a char to a string
342360
fn unshift_char(&s: ~str, ch: char) { s = from_char(ch) + s; }
343361

@@ -423,6 +441,18 @@ pure fn slice(s: &str, begin: uint, end: uint) -> ~str {
423441
unsafe { unsafe::slice_bytes(s, begin, end) }
424442
}
425443

444+
/**
445+
* Returns a view of the given string from the byte range [`begin`..`end`)
446+
*
447+
* Fails when `begin` and `end` do not point to valid characters or beyond
448+
* the last character of the string
449+
*/
450+
pure fn view(s: &a/str, begin: uint, end: uint) -> &a/str {
451+
assert is_char_boundary(s, begin);
452+
assert is_char_boundary(s, end);
453+
unsafe { unsafe::view_bytes(s, begin, end) }
454+
}
455+
426456
/// Splits a string into substrings at each occurrence of a given character
427457
pure fn split_char(s: &str, sep: char) -> ~[~str] {
428458
split_char_inner(s, sep, len(s), true)
@@ -1773,6 +1803,7 @@ mod unsafe {
17731803
from_c_str_len,
17741804
from_bytes,
17751805
slice_bytes,
1806+
view_bytes,
17761807
push_byte,
17771808
pop_byte,
17781809
shift_byte,
@@ -1857,6 +1888,27 @@ mod unsafe {
18571888
}
18581889
}
18591890

1891+
/**
1892+
* Takes a bytewise (not UTF-8) view from a string.
1893+
*
1894+
* Returns the substring from [`begin`..`end`).
1895+
*
1896+
* # Failure
1897+
*
1898+
* If begin is greater than end.
1899+
* If end is greater than the length of the string.
1900+
*/
1901+
#[inline]
1902+
unsafe fn view_bytes(s: &str, begin: uint, end: uint) -> &str {
1903+
do as_buf(s) |sbuf, n| {
1904+
assert (begin <= end);
1905+
assert (end <= n);
1906+
1907+
let tuple = (ptr::offset(sbuf, begin), end - begin + 1);
1908+
::unsafe::reinterpret_cast(tuple)
1909+
}
1910+
}
1911+
18601912
/// Appends a byte to a string. (Not UTF-8 safe).
18611913
unsafe fn push_byte(&s: ~str, b: u8) {
18621914
rustrt::rust_str_push(s, b);
@@ -1958,6 +2010,7 @@ trait StrSlice {
19582010
fn escape_default() -> ~str;
19592011
fn escape_unicode() -> ~str;
19602012
pure fn to_unique() -> ~str;
2013+
pure fn char_at(i: uint) -> char;
19612014
}
19622015

19632016
/// Extension methods for strings
@@ -2067,6 +2120,9 @@ impl &str: StrSlice {
20672120

20682121
#[inline]
20692122
pure fn to_unique() -> ~str { self.slice(0, self.len()) }
2123+
2124+
#[inline]
2125+
pure fn char_at(i: uint) -> char { char_at(self, i) }
20702126
}
20712127

20722128
#[cfg(test)]

0 commit comments

Comments
 (0)