diff options
| author | NODA, Kai <nodakai@gmail.com> | 2014-11-23 19:37:33 +0800 |
|---|---|---|
| committer | NODA, Kai <nodakai@gmail.com> | 2014-11-23 20:05:58 +0800 |
| commit | ef3b88c5f936921fc3ba7968af3dcf1724a17551 (patch) | |
| tree | 3725a34dfdf0b0df22a7c0290b7c1ddded77faa5 | |
| parent | 5ff10d5a230acde7e530ccee8cd4f805d6be7713 (diff) | |
| download | rust-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.rs | 111 |
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] |
