about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2012-08-25 23:13:31 -0700
committerPatrick Walton <pcwalton@mimiga.net>2012-08-25 23:13:50 -0700
commitdb71ff3eb61bbce3123f62b274100dadf5ca99a6 (patch)
treeae8187611d896ef029da944b8f98f5cfd741c110 /src
parent80429dd7bdb94cf11aba1fdfd7a149458a5a6f28 (diff)
downloadrust-db71ff3eb61bbce3123f62b274100dadf5ca99a6.tar.gz
rust-db71ff3eb61bbce3123f62b274100dadf5ca99a6.zip
libcore: Add some methods to make working with string slices easier
Diffstat (limited to 'src')
-rw-r--r--src/libcore/str.rs56
1 files changed, 56 insertions, 0 deletions
diff --git a/src/libcore/str.rs b/src/libcore/str.rs
index d4c8afcd4b3..cf6d7dc3db6 100644
--- a/src/libcore/str.rs
+++ b/src/libcore/str.rs
@@ -32,6 +32,7 @@ export
    push_char,
    pop_char,
    shift_char,
+   view_shift_char,
    unshift_char,
    trim_left,
    trim_right,
@@ -43,6 +44,7 @@ export
    chars,
    substr,
    slice,
+   view,
    split, splitn, split_nonempty,
    split_char, splitn_char, split_char_nonempty,
    split_str, split_str_nonempty,
@@ -338,6 +340,22 @@ fn shift_char(&s: ~str) -> char {
     return ch;
 }
 
+/**
+ * Removes the first character from a string slice and returns it. This does
+ * not allocate a new string; instead, it mutates a slice to point one
+ * character beyond the character that was shifted.
+ *
+ * # Failure
+ *
+ * If the string does not contain any characters
+ */
+#[inline]
+fn view_shift_char(s: &a/str) -> (char, &a/str) {
+    let {ch, next} = char_range_at(s, 0u);
+    let next_s = unsafe { unsafe::view_bytes(s, next, len(s)) };
+    return (ch, next_s);
+}
+
 /// Prepend a char to a string
 fn unshift_char(&s: ~str, ch: char) { s = from_char(ch) + s; }
 
@@ -423,6 +441,18 @@ pure fn slice(s: &str, begin: uint, end: uint) -> ~str {
     unsafe { unsafe::slice_bytes(s, begin, end) }
 }
 
+/**
+ * Returns a view of the given string from the byte range [`begin`..`end`)
+ *
+ * Fails when `begin` and `end` do not point to valid characters or beyond
+ * the last character of the string
+ */
+pure fn view(s: &a/str, begin: uint, end: uint) -> &a/str {
+    assert is_char_boundary(s, begin);
+    assert is_char_boundary(s, end);
+    unsafe { unsafe::view_bytes(s, begin, end) }
+}
+
 /// Splits a string into substrings at each occurrence of a given character
 pure fn split_char(s: &str, sep: char) -> ~[~str] {
     split_char_inner(s, sep, len(s), true)
@@ -1773,6 +1803,7 @@ mod unsafe {
       from_c_str_len,
       from_bytes,
       slice_bytes,
+      view_bytes,
       push_byte,
       pop_byte,
       shift_byte,
@@ -1857,6 +1888,27 @@ mod unsafe {
        }
    }
 
+   /**
+    * Takes a bytewise (not UTF-8) view from a string.
+    *
+    * Returns the substring from [`begin`..`end`).
+    *
+    * # Failure
+    *
+    * If begin is greater than end.
+    * If end is greater than the length of the string.
+    */
+   #[inline]
+   unsafe fn view_bytes(s: &str, begin: uint, end: uint) -> &str {
+       do as_buf(s) |sbuf, n| {
+            assert (begin <= end);
+            assert (end <= n);
+
+            let tuple = (ptr::offset(sbuf, begin), end - begin + 1);
+            ::unsafe::reinterpret_cast(tuple)
+       }
+   }
+
    /// Appends a byte to a string. (Not UTF-8 safe).
    unsafe fn push_byte(&s: ~str, b: u8) {
        rustrt::rust_str_push(s, b);
@@ -1958,6 +2010,7 @@ trait StrSlice {
     fn escape_default() -> ~str;
     fn escape_unicode() -> ~str;
     pure fn to_unique() -> ~str;
+    pure fn char_at(i: uint) -> char;
 }
 
 /// Extension methods for strings
@@ -2067,6 +2120,9 @@ impl &str: StrSlice {
 
     #[inline]
     pure fn to_unique() -> ~str { self.slice(0, self.len()) }
+
+    #[inline]
+    pure fn char_at(i: uint) -> char { char_at(self, i) }
 }
 
 #[cfg(test)]