Skip to main content

TryExtend

Trait TryExtend 

Source
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§

Source

type Error

The type of error that can occur during extension.

Required Methods§

Source

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)>,

Source§

type Error = ExtendError<<I as IntoIterator>::IntoIter, <HashMap<K, V, S> as TryExtendOne>::Error>

Source§

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)>,

Source§

type Error = ExtendError<<I as IntoIterator>::IntoIter, <HashMap<K, V, S> as TryExtendOne>::Error>

Source§

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)>,

Source§

type Error = ExtendError<<I as IntoIterator>::IntoIter, <IndexMap<K, V, S> as TryExtendOne>::Error>

Source§

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)>,

Source§

type Error = ExtendError<<I as IntoIterator>::IntoIter, <BTreeMap<K, V> as TryExtendOne>::Error>

Source§

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>,

Extends an ArrayVec with an iterator, failing if the iterator produces more items than the ArrayVec’s remaining capacity.

Source§

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");
Source§

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>,

Source§

type Error = ExtendError<<I as IntoIterator>::IntoIter, <HashSet<T, S> as TryExtendOne>::Error>

Source§

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>,

Source§

type Error = ExtendError<<I as IntoIterator>::IntoIter, <HashSet<T, S> as TryExtendOne>::Error>

Source§

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>,

Source§

type Error = ExtendError<<I as IntoIterator>::IntoIter, <IndexSet<T, S> as TryExtendOne>::Error>

Source§

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>,

Source§

type Error = ExtendError<<I as IntoIterator>::IntoIter, <BTreeSet<T> as TryExtendOne>::Error>

Source§

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).

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>

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");
Source§

type Error = Either<TupleExtendError<<TryFromA as TryExtendOne>::Error, <TryFromB as TryExtendOne>::Item, <I as IntoIterator>::IntoIter>, TupleExtendError<<TryFromB as TryExtendOne>::Error, <TryFromA as TryExtendOne>::Item, <I as IntoIterator>::IntoIter>>

Implementors§