about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNODA, Kai <nodakai@gmail.com>2014-11-23 19:37:33 +0800
committerNODA, Kai <nodakai@gmail.com>2014-11-23 20:05:58 +0800
commitef3b88c5f936921fc3ba7968af3dcf1724a17551 (patch)
tree3725a34dfdf0b0df22a7c0290b7c1ddded77faa5
parent5ff10d5a230acde7e530ccee8cd4f805d6be7713 (diff)
downloadrust-ef3b88c5f936921fc3ba7968af3dcf1724a17551.tar.gz
rust-ef3b88c5f936921fc3ba7968af3dcf1724a17551.zip
libcollection: generalize StrVector to AsSlice<Str>.
The impl for [T] also works as impl for slices in general.
By generalizing the impl of StrVector for Vec<Str> to that for
AsSlice<Str>, it becomes much more generic.

Once Iterable is implemented, we will prefer it to AsSlice.
But the with_capacity() part might become tricky.

Signed-off-by: NODA, Kai <nodakai@gmail.com>
-rw-r--r--src/libcollections/str.rs111
1 files changed, 75 insertions, 36 deletions
diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs
index 67c8902ffc9..9982eaefff8 100644
--- a/src/libcollections/str.rs
+++ b/src/libcollections/str.rs
@@ -163,7 +163,7 @@ impl<S: Str> StrVector for [S] {
     }
 }
 
-impl<S: Str> StrVector for Vec<S> {
+impl<S: Str, T: AsSlice<S>> StrVector for T {
     #[inline]
     fn concat(&self) -> String {
         self.as_slice().concat()
@@ -929,54 +929,93 @@ mod tests {
         assert_eq!("ะเทศไท", "ประเทศไทย中华Việt Nam".slice_chars(2, 8));
     }
 
-    #[test]
-    fn test_concat() {
-        fn t(v: &[String], s: &str) {
-            assert_eq!(v.concat().as_slice(), s);
+    struct S {
+        x: [String, .. 2]
+    }
+
+    impl AsSlice<String> for S {
+        fn as_slice<'a> (&'a self) -> &'a [String] {
+            &self.x
+        }
+    }
+
+    fn s(x: &str) -> String { x.into_string() }
+
+    macro_rules! test_concat {
+        ($expected: expr, $string: expr) => {
+            {
+                let s = $string.concat();
+                assert_eq!($expected, s.as_slice());
+            }
         }
-        t(&[String::from_str("you"), String::from_str("know"),
-            String::from_str("I'm"),
-            String::from_str("no"), String::from_str("good")],
-          "youknowI'mnogood");
-        let v: &[String] = &[];
-        t(v, "");
-        t(&[String::from_str("hi")], "hi");
     }
 
     #[test]
-    fn test_connect() {
-        fn t(v: &[String], sep: &str, s: &str) {
-            assert_eq!(v.connect(sep).as_slice(), s);
+    fn test_concat_for_different_types() {
+        test_concat!("ab", ["a", "b"]);
+        test_concat!("ab", [s("a"), s("b")]);
+        test_concat!("ab", vec!["a", "b"]);
+        test_concat!("ab", vec!["a", "b"].as_slice());
+        test_concat!("ab", vec![s("a"), s("b")]);
+
+        let mut v0 = ["a", "b"];
+        let mut v1 = [s("a"), s("b")];
+        unsafe {
+            use std::c_vec::CVec;
+
+            test_concat!("ab", CVec::new(v0.as_mut_ptr(), v0.len()));
+            test_concat!("ab", CVec::new(v1.as_mut_ptr(), v1.len()));
         }
-        t(&[String::from_str("you"), String::from_str("know"),
-            String::from_str("I'm"),
-            String::from_str("no"), String::from_str("good")],
-          " ", "you know I'm no good");
-        let v: &[String] = &[];
-        t(v, " ", "");
-        t(&[String::from_str("hi")], " ", "hi");
+
+        test_concat!("ab", S { x: [s("a"), s("b")] });
     }
 
     #[test]
-    fn test_concat_slices() {
-        fn t(v: &[&str], s: &str) {
-            assert_eq!(v.concat().as_slice(), s);
+    fn test_concat_for_different_lengths() {
+        let empty: &[&str] = &[];
+        test_concat!("", empty);
+        test_concat!("a", ["a"]);
+        test_concat!("ab", ["a", "b"]);
+        test_concat!("abc", ["", "a", "bc"]);
+    }
+
+    macro_rules! test_connect {
+        ($expected: expr, $string: expr, $delim: expr) => {
+            {
+                let s = $string.connect($delim);
+                assert_eq!($expected, s.as_slice());
+            }
         }
-        t(&["you", "know", "I'm", "no", "good"], "youknowI'mnogood");
-        let v: &[&str] = &[];
-        t(v, "");
-        t(&["hi"], "hi");
     }
 
     #[test]
-    fn test_connect_slices() {
-        fn t(v: &[&str], sep: &str, s: &str) {
-            assert_eq!(v.connect(sep).as_slice(), s);
+    fn test_connect_for_different_types() {
+        test_connect!("a-b", ["a", "b"], "-");
+        let hyphen = "-".into_string();
+        test_connect!("a-b", [s("a"), s("b")], hyphen.as_slice());
+        test_connect!("a-b", vec!["a", "b"], hyphen.as_slice());
+        test_connect!("a-b", vec!["a", "b"].as_slice(), "-");
+        test_connect!("a-b", vec![s("a"), s("b")], "-");
+
+        let mut v0 = ["a", "b"];
+        let mut v1 = [s("a"), s("b")];
+        unsafe {
+            use std::c_vec::CVec;
+
+            test_connect!("a-b", CVec::new(v0.as_mut_ptr(), v0.len()), "-");
+            test_connect!("a-b", CVec::new(v1.as_mut_ptr(), v1.len()), hyphen.as_slice());
         }
-        t(&["you", "know", "I'm", "no", "good"],
-          " ", "you know I'm no good");
-        t(&[], " ", "");
-        t(&["hi"], " ", "hi");
+
+        test_connect!("a-b", S { x: [s("a"), s("b")] }, "-");
+    }
+
+    #[test]
+    fn test_connect_for_different_lengths() {
+        let empty: &[&str] = &[];
+        test_connect!("", empty, "-");
+        test_connect!("a", ["a"], "-");
+        test_connect!("a-b", ["a", "b"], "-");
+        test_connect!("-a-bc", ["", "a", "bc"], "-");
     }
 
     #[test]