pub trait TryExtend<I: IntoIterator> {
type Error;
// Required method
fn try_extend(&mut self, iter: I) -> Result<(), Self::Error>;
}Expand description
Trait for extending an existing collection from an iterator with fallible operations.
This trait is similar to Extend, but allows implementor to uphold a container’s invariant
during construction with a basic error guarantee. On an error, the collection may be
modified, but will be in a valid state. The specific extension that triggers the error must
not be inserted.
For a stronger error guarantee where the collection is unchanged on error, see
TryExtendSafe.
Implementations may rely on Iterator::size_hint providing reliable bounds for the number of
elements in the iterator in order to optimize their implementations. An iterator that violates
the bounds returned by Iterator::size_hint may cause panics, produce incorrect results, or
produce a result that violates container constraints, but must not result in undefined behavior.
Required Associated Types§
Required Methods§
Sourcefn try_extend(&mut self, iter: I) -> Result<(), Self::Error>
fn try_extend(&mut self, iter: I) -> Result<(), Self::Error>
Tries to extends the collection providing a basic error guarantee.
On failure, the collection may be partially modified, but it must remain valid. The specific extension that triggers the error must not be inserted.
For strong guarantee needs, see TryExtendSafe::try_extend_safe.
§Errors
Returns TryExtend::Error if a failure occurs while extending the collection.
§Examples
The provided HashMap implementation errors if a key collision occurs during extension.
let mut map = HashMap::from([(1, 2)]);
let err = map.try_extend([(2, 3), (1, 5), (3, 4)]).expect_err("should collide");
assert_eq!(err.error.item, (1, 5), "item should be the colliding item");
assert_eq!(map[&1], 2, "colliding value should not be changed");
let remaining: Vec<_> = err.into_data().remain.collect();
assert_eq!(remaining, vec![(3, 4)], "Error should contain the remaining items");Implementations on Foreign Types§
Source§impl<K: Eq + Hash, V, S: BuildHasher + Clone, I> TryExtend<I> for HashMap<K, V, S>where
I: IntoIterator<Item = (K, V)>,
impl<K: Eq + Hash, V, S: BuildHasher + Clone, I> TryExtend<I> for HashMap<K, V, S>where
I: IntoIterator<Item = (K, V)>,
type Error = ExtendError<<I as IntoIterator>::IntoIter, <HashMap<K, V, S> as TryExtendOne>::Error>
fn try_extend(&mut self, into_iter: I) -> Result<(), Self::Error>where
Self: Sized,
Source§impl<K: Eq + Hash, V, S: BuildHasher + Clone, I> TryExtend<I> for HashMap<K, V, S>where
I: IntoIterator<Item = (K, V)>,
impl<K: Eq + Hash, V, S: BuildHasher + Clone, I> TryExtend<I> for HashMap<K, V, S>where
I: IntoIterator<Item = (K, V)>,
type Error = ExtendError<<I as IntoIterator>::IntoIter, <HashMap<K, V, S> as TryExtendOne>::Error>
fn try_extend(&mut self, into_iter: I) -> Result<(), Self::Error>where
Self: Sized,
Source§impl<K: Eq + Hash, V, S: BuildHasher + Clone, I> TryExtend<I> for IndexMap<K, V, S>where
I: IntoIterator<Item = (K, V)>,
impl<K: Eq + Hash, V, S: BuildHasher + Clone, I> TryExtend<I> for IndexMap<K, V, S>where
I: IntoIterator<Item = (K, V)>,
type Error = ExtendError<<I as IntoIterator>::IntoIter, <IndexMap<K, V, S> as TryExtendOne>::Error>
fn try_extend(&mut self, into_iter: I) -> Result<(), Self::Error>where
Self: Sized,
Source§impl<K: Ord, V, I> TryExtend<I> for BTreeMap<K, V>where
I: IntoIterator<Item = (K, V)>,
impl<K: Ord, V, I> TryExtend<I> for BTreeMap<K, V>where
I: IntoIterator<Item = (K, V)>,
type Error = ExtendError<<I as IntoIterator>::IntoIter, <BTreeMap<K, V> as TryExtendOne>::Error>
fn try_extend(&mut self, into_iter: I) -> Result<(), Self::Error>where
Self: Sized,
Source§impl<T, const N: usize, I> TryExtend<I> for ArrayVec<T, N>where
I: IntoIterator<Item = T>,
impl<T, const N: usize, I> TryExtend<I> for ArrayVec<T, N>where
I: IntoIterator<Item = T>,
Source§fn try_extend(&mut self, iter: I) -> Result<(), Self::Error>
fn try_extend(&mut self, iter: I) -> Result<(), Self::Error>
Appends iter to the ArrayVec, failing if iter produces more
items than ArrayVec::remaining_capacity.
§Errors
Returns an ExtendError if iter produces more items than ArrayVec::remaining_capacity. The CapacityError::capacity in that error will reflect
This method provides a basic error guarantee. If the method returns
an error, the ArrayVec is valid, but may be modified.
§Panics
Panics if iter’s size_hint is invalid.
§Examples
let mut array: ArrayVec<i32, 4> = (1..=2).try_collect_ex()?;
array.try_extend([3])?;
assert_eq!(*array, [1, 2, 3], "array should contain 3 items");
let err = array.try_extend([4, 5]).expect_err("should fail with too many items");
let all_items = array.into_iter().chain(err).collect::<Vec<_>>();
assert_eq!(all_items, [1, 2, 3, 4, 5], "no items should be lost");type Error = ExtendError<<I as IntoIterator>::IntoIter, CapacityError<T>>
Source§impl<T: Eq + Hash, S: BuildHasher + Clone, I> TryExtend<I> for HashSet<T, S>where
I: IntoIterator<Item = T>,
impl<T: Eq + Hash, S: BuildHasher + Clone, I> TryExtend<I> for HashSet<T, S>where
I: IntoIterator<Item = T>,
type Error = ExtendError<<I as IntoIterator>::IntoIter, <HashSet<T, S> as TryExtendOne>::Error>
fn try_extend(&mut self, into_iter: I) -> Result<(), Self::Error>where
Self: Sized,
Source§impl<T: Eq + Hash, S: BuildHasher + Clone, I> TryExtend<I> for HashSet<T, S>where
I: IntoIterator<Item = T>,
impl<T: Eq + Hash, S: BuildHasher + Clone, I> TryExtend<I> for HashSet<T, S>where
I: IntoIterator<Item = T>,
type Error = ExtendError<<I as IntoIterator>::IntoIter, <HashSet<T, S> as TryExtendOne>::Error>
fn try_extend(&mut self, into_iter: I) -> Result<(), Self::Error>where
Self: Sized,
Source§impl<T: Eq + Hash, S: BuildHasher + Clone, I> TryExtend<I> for IndexSet<T, S>where
I: IntoIterator<Item = T>,
impl<T: Eq + Hash, S: BuildHasher + Clone, I> TryExtend<I> for IndexSet<T, S>where
I: IntoIterator<Item = T>,
type Error = ExtendError<<I as IntoIterator>::IntoIter, <IndexSet<T, S> as TryExtendOne>::Error>
fn try_extend(&mut self, into_iter: I) -> Result<(), Self::Error>where
Self: Sized,
Source§impl<T: Ord, I> TryExtend<I> for BTreeSet<T>where
I: IntoIterator<Item = T>,
impl<T: Ord, I> TryExtend<I> for BTreeSet<T>where
I: IntoIterator<Item = T>,
type Error = ExtendError<<I as IntoIterator>::IntoIter, <BTreeSet<T> as TryExtendOne>::Error>
fn try_extend(&mut self, into_iter: I) -> Result<(), Self::Error>where
Self: Sized,
Source§impl<TryFromA, TryFromB, I> TryExtend<I> for (TryFromA, TryFromB)where
I: IntoIterator<Item = (TryFromA::Item, TryFromB::Item)>,
TryFromA: TryExtendOne + Default,
TryFromB: TryExtendOne + Default,
Extends an (TryFromA, TryFromB) collection with the contents of an iterator of (A, B).
impl<TryFromA, TryFromB, I> TryExtend<I> for (TryFromA, TryFromB)where
I: IntoIterator<Item = (TryFromA::Item, TryFromB::Item)>,
TryFromA: TryExtendOne + Default,
TryFromB: TryExtendOne + Default,
Extends an (TryFromA, TryFromB) collection with the contents of an iterator of (A, B).
Note: Tuples do not implement TryExtendSafe because they cannot
provide a strong error guarantee. Extension has to proceed element by element and if the
second collection fails to extend, the first may have already been modified.
Source§fn try_extend(&mut self, iter: I) -> Result<(), Self::Error>
fn try_extend(&mut self, iter: I) -> Result<(), Self::Error>
Extends an (TryFromA, TryFromB) collection with the contents of an iterator of (A, B).
This method provides a basic error guarantee. If the method returns an error, one or both collections may have been partially modified.
§Examples
use collect_failable::TryExtend;
use std::collections::HashMap;
let pairs = [((1, 1), (2, 2)), ((3, 3), (4, 4))];
let mut tuple_of_maps = (HashMap::new(), HashMap::new());
tuple_of_maps.try_extend(pairs).expect("should extend both collections");
assert_eq!(tuple_of_maps.0, HashMap::from([(1, 1), (3, 3)]), "should contain all items");
assert_eq!(tuple_of_maps.1, HashMap::from([(2, 2), (4, 4)]), "should contain all items");
let colliding_pairs = [((5, 5), (6, 6)), ((1, 10), (7, 7))];
let extend_err = tuple_of_maps.try_extend(colliding_pairs).expect_err("should collide on second item");
let err_side = extend_err.as_ref().left().expect("should collide on left side");
assert_eq!(err_side.error.item, (1, 10), "should contain colliding item");
assert_eq!(tuple_of_maps.0[&1], 1, "value should not be modified");