Expand description
§collect_failable
A set of traits for collecting values into containers that must uphold invariants during construction or extension. These traits let you propagate structured errors instead of panicking or silently discarding data. Examples include preventing duplicate keys in a HashMap or respecting capacity limits in types like ArrayVec.
§Traits
This crate provides several complementary traits for failable collection:
TryFromIterator– failably build a container from anIntoIterator.TryCollectEx– failably collect anIntoIteratorinto a container.TryExtendandTryExtendSafe– failably extend a container with anIntoIterator, with different error guarantees.TryExtendOne– failable extend a container with a single item.TryUnzip– failably unzip anIntoIteratorof pairs into two containers (requires featuretuple, enabled by default).
Additionally, several implementations are provided for common and popular containers. See the implementations section for more details.
§Installation
It’s on crates.io.
§Features
This crate provides the following optional features:
alloc(default) – Enables support for allocation-dependent types (BTreeMap,BTreeSet,Result,Rc,Vec,Box). Required for most functionality. When disabled, only the core traits are available.std(default) – Enables standard library support, includingHashMapandHashSetimplementations. When disabled, the crate operates inno_stdmode withalloc.unsafe(default) – EnablesTryFromIteratorimplementations for arrays using unsafe code.tuple(default) – Enables tuple extension (TryExtendfor tuples) andTryUnziptrait, requiring a public dependency on theeithercrate (re-exported ascollect_failable::Either).arrayvec– EnablesTryFromIteratorandTryExtendimplementations forArrayVec.hashbrown– EnablesTryFromIteratorandTryExtendimplementations forhashbrown::HashMapandhashbrown::HashSet.indexmap– EnablesTryFromIteratorandTryExtendimplementations forindexmap::IndexMapandindexmap::IndexSet.
§No-std Support
This crate supports no_std environments when the std feature is disabled. The alloc feature provides allocation-dependent functionality (BTreeMap, BTreeSet, etc.) without requiring the full standard library.
Note: HashMap and HashSet require the std feature because they depend on the standard library’s default hasher. For no_std environments, consider BTreeMap/BTreeSet (with alloc) or hashbrown/indexmap (with their respective features).
§Usage
§TryFromIterator and TryCollectEx
Construct a container from an iterator, with errors for invalid input. This behaves like FromIterator but returns Result<Self, E> instead of panicking or ignoring failures.
use std::collections::HashMap;
use collect_failable::{TryFromIterator, TryCollectEx};
// can be called on any type that implements TryFromIterator
let err = HashMap::try_from_iter([(1, 2), (2, 3), (1, 4), (3, 5)]).expect_err("should be Err");
assert_eq!(err.item.0, 1); // err.item is the colliding (K, V) tuple
// For `HashMap` the error contains all the data necessary to reconstruct the consumed iterator
let all_items: Vec<_> = err.into_iter().collect();
assert_eq!(all_items.len(), 4); // all 4 original items are present, though order is not guaranteed
// or collected via the TryCollectEx trait a turbofish may be necessary to disambiguate
let map = [(1, 2), (2, 3)].into_iter().try_collect_ex::<HashMap<_, _>>().expect("should be Ok");
assert_eq!(map, HashMap::from([(1, 2), (2, 3)]));
// or type ascription. Note the Result type can be inferred, just not the collection type.
let map: HashMap<_, _> = [(1, 2), (2, 3)].into_iter().try_collect_ex().expect("should be Ok");
assert_eq!(map, HashMap::from([(1, 2), (2, 3)]));§TryExtend and TryExtendSafe
Extend an existing container with items that may violate its invariants. Two different trait exposes two styles of error behavior:
TryExtendSafe– strong guarantee on an error, the container must remain unchanged.TryExtend– basic guarantee the container may have partially ingested items, but must remain valid.
Use TryExtendSafe if you must avoid mutation on failure; otherwise, prefer the faster TryExtend.
use std::collections::HashMap;
use collect_failable::TryExtendSafe;
let mut map = HashMap::new();
map.try_extend_safe([(1, 2), (2, 3)]).expect("should be Ok");
assert_eq!(map, HashMap::from([(1, 2), (2, 3)]));
// on a failure, the container is not modified
map.try_extend_safe([(1, 3)]).expect_err("should be Err");
assert_eq!(map, HashMap::from([(1, 2), (2, 3)]));§TryExtendOne
Extend a collection with a single item. This trait always provides a strong guarantee: on failure, the collection remains unchanged. Implemented as a seperate trait with no default implementation due to limitations imposed by the trait definition.
§TryUnzip
Fallible equivalent of Iterator::unzip. Given an iterator of (A, B) items, produce two collections that implement Default + TryExtend, stopping on the first failure.
Allows unzipping an iterator of pairs into two collections that implement Default and TryExtend.
This is analogous to Iterator::unzip, except allows for failable construction.
use std::collections::{BTreeSet, HashSet};
use collect_failable::TryUnzip;
// Unzip into two different container types
let data = vec![(1, 'a'), (2, 'b'), (3, 'c')];
let (nums, chars): (BTreeSet<i32>, HashSet<char>) = data.into_iter().try_unzip().expect("should be ok");
assert_eq!(nums, BTreeSet::from([1, 2, 3]));
assert_eq!(chars, HashSet::from(['a', 'b', 'c']));§Implementations
Implementations for various containers are provided.
- HashMap, HashSet (feature
std, enabled by default) - BTreeMap, BTreeSet (feature
alloc, enabled by default) - Array (feature
unsafe, enabled by default) - ArrayVec (feature
arrayvec) - hashbrown::HashMap, hashbrown::HashSet (feature
hashbrown) - indexmap::IndexMap, indexmap::IndexSet (feature
indexmap)
§Tuple Implementations
Tuples of arity 2 implement TryExtend when their inner types do (requires feature tuple, enabled by default). For constructing tuple collections from IntoIterator TryUnzip is available.
§Array Implementation
Arrays implement TryFromIterator for IntoIterator that yield exactly the right number of elements. This uses unsafe internally and is gated behind the unsafe feature (enabled by default).
§Result Implementation
TryFromIterator is implemented for Result<C, E>, where C implements TryFromIterator<T>, similar to the FromIterator implementation for Result. This allows short-circuiting collection of failable values into a container whose construction is also failable.
Modules§
- either
- Re-export of the
Eithertype from theeithercrate. - errors
- Error types returned by provided failable collection operation implementations.
Traits§
- TryCollect
Ex - Extends Iterator with a failable collect method.
- TryExtend
- Trait for extending an existing collection from an iterator with fallible operations.
- TryExtend
One - Extension trait providing convenience method for extending a collection with a single item.
- TryExtend
Safe - Trait for extending a collection with a strong error guarantee.
- TryFrom
Iterator - Tries to convert a
IntoIteratorinto a container that may fail to be constructed. - TryUnzip
- Extends
Iteratorwith a failable unzip method.