|
32 | 32 | push_char,
|
33 | 33 | pop_char,
|
34 | 34 | shift_char,
|
| 35 | + view_shift_char, |
35 | 36 | unshift_char,
|
36 | 37 | trim_left,
|
37 | 38 | trim_right,
|
|
43 | 44 | chars,
|
44 | 45 | substr,
|
45 | 46 | slice,
|
| 47 | + view, |
46 | 48 | split, splitn, split_nonempty,
|
47 | 49 | split_char, splitn_char, split_char_nonempty,
|
48 | 50 | split_str, split_str_nonempty,
|
@@ -338,6 +340,22 @@ fn shift_char(&s: ~str) -> char {
|
338 | 340 | return ch;
|
339 | 341 | }
|
340 | 342 |
|
| 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 | + |
341 | 359 | /// Prepend a char to a string
|
342 | 360 | fn unshift_char(&s: ~str, ch: char) { s = from_char(ch) + s; }
|
343 | 361 |
|
@@ -423,6 +441,18 @@ pure fn slice(s: &str, begin: uint, end: uint) -> ~str {
|
423 | 441 | unsafe { unsafe::slice_bytes(s, begin, end) }
|
424 | 442 | }
|
425 | 443 |
|
| 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 | + |
426 | 456 | /// Splits a string into substrings at each occurrence of a given character
|
427 | 457 | pure fn split_char(s: &str, sep: char) -> ~[~str] {
|
428 | 458 | split_char_inner(s, sep, len(s), true)
|
@@ -1773,6 +1803,7 @@ mod unsafe {
|
1773 | 1803 | from_c_str_len,
|
1774 | 1804 | from_bytes,
|
1775 | 1805 | slice_bytes,
|
| 1806 | + view_bytes, |
1776 | 1807 | push_byte,
|
1777 | 1808 | pop_byte,
|
1778 | 1809 | shift_byte,
|
@@ -1857,6 +1888,27 @@ mod unsafe {
|
1857 | 1888 | }
|
1858 | 1889 | }
|
1859 | 1890 |
|
| 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 | + |
1860 | 1912 | /// Appends a byte to a string. (Not UTF-8 safe).
|
1861 | 1913 | unsafe fn push_byte(&s: ~str, b: u8) {
|
1862 | 1914 | rustrt::rust_str_push(s, b);
|
@@ -1958,6 +2010,7 @@ trait StrSlice {
|
1958 | 2010 | fn escape_default() -> ~str;
|
1959 | 2011 | fn escape_unicode() -> ~str;
|
1960 | 2012 | pure fn to_unique() -> ~str;
|
| 2013 | + pure fn char_at(i: uint) -> char; |
1961 | 2014 | }
|
1962 | 2015 |
|
1963 | 2016 | /// Extension methods for strings
|
@@ -2067,6 +2120,9 @@ impl &str: StrSlice {
|
2067 | 2120 |
|
2068 | 2121 | #[inline]
|
2069 | 2122 | 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) } |
2070 | 2126 | }
|
2071 | 2127 |
|
2072 | 2128 | #[cfg(test)]
|
|
0 commit comments