Libs: Unify concat and concat_vec
We've long had traits `StrVector` and `VectorVector` providing `concat`/`connect` and `concat_vec`/`connect_vec` respectively. The reason for the distinction is that coherence rules did not used to be robust enough to allow impls on e.g. `Vec<String>` versus `Vec<&[T]>`. This commit consolidates the traits into a single `SliceConcatExt` trait provided by `slice` and the preldue (where it replaces `StrVector`, which is removed.) [breaking-change]
This commit is contained in:
parent
4f863a338e
commit
e91d810b9b
|
@ -993,19 +993,31 @@ impl<T: Ord> OrdSliceExt<T> for [T] {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(missing_docs)]
|
#[unstable = "U should be an associated type"]
|
||||||
pub trait VectorVector<T> for Sized? {
|
/// An extension trait for concatenating slices
|
||||||
// FIXME #5898: calling these .concat and .connect conflicts with
|
pub trait SliceConcatExt<Sized? T, U> for Sized? {
|
||||||
// StrVector::con{cat,nect}, since they have generic contents.
|
/// Flattens a slice of `T` into a single value `U`.
|
||||||
/// Flattens a vector of vectors of `T` into a single `Vec<T>`.
|
#[stable]
|
||||||
fn concat_vec(&self) -> Vec<T>;
|
fn concat(&self) -> U;
|
||||||
|
|
||||||
/// Concatenate a vector of vectors, placing a given separator between each.
|
#[deprecated = "renamed to concat"]
|
||||||
fn connect_vec(&self, sep: &T) -> Vec<T>;
|
fn concat_vec(&self) -> U {
|
||||||
|
self.concat()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Flattens a slice of `T` into a single value `U`, placing a
|
||||||
|
/// given seperator between each.
|
||||||
|
#[stable]
|
||||||
|
fn connect(&self, sep: &T) -> U;
|
||||||
|
|
||||||
|
#[deprecated = "renamed to connect"]
|
||||||
|
fn connect_vec(&self, sep: &T) -> U {
|
||||||
|
self.connect(sep)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Clone, V: AsSlice<T>> VectorVector<T> for [V] {
|
impl<T: Clone, V: AsSlice<T>> SliceConcatExt<T, Vec<T>> for [V] {
|
||||||
fn concat_vec(&self) -> Vec<T> {
|
fn concat(&self) -> Vec<T> {
|
||||||
let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len());
|
let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len());
|
||||||
let mut result = Vec::with_capacity(size);
|
let mut result = Vec::with_capacity(size);
|
||||||
for v in self.iter() {
|
for v in self.iter() {
|
||||||
|
@ -1014,7 +1026,7 @@ impl<'a, T: Clone, V: AsSlice<T>> VectorVector<T> for [V] {
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn connect_vec(&self, sep: &T) -> Vec<T> {
|
fn connect(&self, sep: &T) -> Vec<T> {
|
||||||
let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len());
|
let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len());
|
||||||
let mut result = Vec::with_capacity(size + self.len());
|
let mut result = Vec::with_capacity(size + self.len());
|
||||||
let mut first = true;
|
let mut first = true;
|
||||||
|
|
|
@ -77,6 +77,7 @@ use slice::SliceExt;
|
||||||
use string::String;
|
use string::String;
|
||||||
use unicode;
|
use unicode;
|
||||||
use vec::Vec;
|
use vec::Vec;
|
||||||
|
use slice::SliceConcatExt;
|
||||||
|
|
||||||
pub use core::str::{from_utf8, CharEq, Chars, CharIndices};
|
pub use core::str::{from_utf8, CharEq, Chars, CharIndices};
|
||||||
pub use core::str::{Bytes, CharSplits, is_utf8};
|
pub use core::str::{Bytes, CharSplits, is_utf8};
|
||||||
|
@ -93,36 +94,7 @@ pub use core::str::{SplitN, RSplitN};
|
||||||
Section: Creating a string
|
Section: Creating a string
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/// Methods for vectors of strings.
|
impl<S: Str> SliceConcatExt<str, String> for [S] {
|
||||||
#[unstable = "functionality may be replaced with iterators"]
|
|
||||||
pub trait StrVector for Sized? {
|
|
||||||
/// Concatenates a vector of strings.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// let first = "Restaurant at the End of the".to_string();
|
|
||||||
/// let second = " Universe".to_string();
|
|
||||||
/// let string_vec = vec![first, second];
|
|
||||||
/// assert_eq!(string_vec.concat(), "Restaurant at the End of the Universe".to_string());
|
|
||||||
/// ```
|
|
||||||
fn concat(&self) -> String;
|
|
||||||
|
|
||||||
/// Concatenates a vector of strings, placing a given separator between each.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// let first = "Roast".to_string();
|
|
||||||
/// let second = "Sirloin Steak".to_string();
|
|
||||||
/// let string_vec = vec![first, second];
|
|
||||||
/// assert_eq!(string_vec.connect(", "), "Roast, Sirloin Steak".to_string());
|
|
||||||
/// ```
|
|
||||||
fn connect(&self, sep: &str) -> String;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(deprecated)]
|
|
||||||
impl<S: Str> StrVector for [S] {
|
|
||||||
fn concat(&self) -> String {
|
fn concat(&self) -> String {
|
||||||
if self.is_empty() {
|
if self.is_empty() {
|
||||||
return String::new();
|
return String::new();
|
||||||
|
@ -169,16 +141,9 @@ impl<S: Str> StrVector for [S] {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Str, T: AsSlice<S>> StrVector for T {
|
impl<S: Str> SliceConcatExt<str, String> for Vec<S> {
|
||||||
#[inline]
|
fn concat(&self) -> String { self[].concat() }
|
||||||
fn concat(&self) -> String {
|
fn connect(&self, sep: &str) -> String { self[].connect(sep) }
|
||||||
self.as_slice().concat()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn connect(&self, sep: &str) -> String {
|
|
||||||
self.as_slice().connect(sep)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -22,7 +22,7 @@ use option::Option::{None, Some};
|
||||||
use kinds::Sized;
|
use kinds::Sized;
|
||||||
use str::{FromStr, Str};
|
use str::{FromStr, Str};
|
||||||
use str;
|
use str;
|
||||||
use slice::{CloneSliceExt, Splits, AsSlice, VectorVector,
|
use slice::{CloneSliceExt, Split, AsSlice, SliceConcatExt,
|
||||||
PartialEqSliceExt, SliceExt};
|
PartialEqSliceExt, SliceExt};
|
||||||
use vec::Vec;
|
use vec::Vec;
|
||||||
|
|
||||||
|
@ -306,7 +306,7 @@ impl GenericPath for Path {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(Path::new(comps.connect_vec(&SEP_BYTE)))
|
Some(Path::new(comps.as_slice().connect(&SEP_BYTE)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,8 +25,8 @@ use iter::{Iterator, IteratorExt, Map, repeat};
|
||||||
use mem;
|
use mem;
|
||||||
use option::Option;
|
use option::Option;
|
||||||
use option::Option::{Some, None};
|
use option::Option::{Some, None};
|
||||||
use slice::SliceExt;
|
use slice::{AsSlice, SliceExt, SliceConcatExt};
|
||||||
use str::{SplitTerminator, FromStr, StrVector, StrExt};
|
use str::{CharSplits, FromStr, Str, StrAllocating, StrPrelude};
|
||||||
use string::{String, ToString};
|
use string::{String, ToString};
|
||||||
use unicode::char::UnicodeChar;
|
use unicode::char::UnicodeChar;
|
||||||
use vec::Vec;
|
use vec::Vec;
|
||||||
|
|
|
@ -80,10 +80,9 @@
|
||||||
#[doc(no_inline)] pub use core::prelude::{Tuple1, Tuple2, Tuple3, Tuple4};
|
#[doc(no_inline)] pub use core::prelude::{Tuple1, Tuple2, Tuple3, Tuple4};
|
||||||
#[doc(no_inline)] pub use core::prelude::{Tuple5, Tuple6, Tuple7, Tuple8};
|
#[doc(no_inline)] pub use core::prelude::{Tuple5, Tuple6, Tuple7, Tuple8};
|
||||||
#[doc(no_inline)] pub use core::prelude::{Tuple9, Tuple10, Tuple11, Tuple12};
|
#[doc(no_inline)] pub use core::prelude::{Tuple9, Tuple10, Tuple11, Tuple12};
|
||||||
#[doc(no_inline)] pub use str::{Str, StrVector};
|
#[doc(no_inline)] pub use str::{Str, StrExt};
|
||||||
#[doc(no_inline)] pub use str::StrExt;
|
|
||||||
#[doc(no_inline)] pub use slice::AsSlice;
|
#[doc(no_inline)] pub use slice::AsSlice;
|
||||||
#[doc(no_inline)] pub use slice::{VectorVector, PartialEqSliceExt};
|
#[doc(no_inline)] pub use slice::{SliceConcatExt, PartialEqSliceExt};
|
||||||
#[doc(no_inline)] pub use slice::{CloneSliceExt, OrdSliceExt, SliceExt};
|
#[doc(no_inline)] pub use slice::{CloneSliceExt, OrdSliceExt, SliceExt};
|
||||||
#[doc(no_inline)] pub use slice::{BoxedSliceExt};
|
#[doc(no_inline)] pub use slice::{BoxedSliceExt};
|
||||||
#[doc(no_inline)] pub use string::{IntoString, String, ToString};
|
#[doc(no_inline)] pub use string::{IntoString, String, ToString};
|
||||||
|
|
Loading…
Reference in New Issue