Crate take_some[−][src]
A simple library that provides a way to obtain some value from various collections.
Sometimes one simply needs to "take" an element from a collection, no matter which element will it be. If you are that one, please feel free to use the crate that aims to make your (yes, yours!) life a tiny bit easier.
Now let's see how it works.
Let's say you want to implement a hash map that is statically guaranteed by the rust's type
system to be non-empy at all the times.
The most straightforward way to do so is to declare it as a pair of an item and the rest of the
items, like struct NonEmptyHashMap<K, V, S> (((K, V), ::std::collections::HashMap<K, V,S>))
.
So far, so good. You will obviously want to create some nice user API for it, and that will
include an instantiation of you type with a normal HashMap
from the standard library. And
here shines the take-some
crate!
extern crate take_some; use std::collections::HashMap; use std::hash::{BuildHasher, Hash}; use take_some::TakeSome; struct NonEmptyHashMap<K, V, S> { first: (K, V), rest: HashMap<K, V, S>, } impl<K, V, S> NonEmptyHashMap<K, V, S> where K: Eq + Hash, S: BuildHasher, { fn from_std_hashmap(mut map: HashMap<K, V, S>) -> Option<Self> { map.take_some() .map(|first| NonEmptyHashMap { first, rest: map }) } // An alternative implementation that takes advantage of the `TakeSome::split_at_some` // method. fn from_std_hashmap2(map: HashMap<K, V, S>) -> Option<Self> { map.split_at_some() .map(|(first, rest)| NonEmptyHashMap { first, rest }) .ok() } } fn main() { let map: HashMap<String, String> = vec![ ("first".into(), "lol".into()), ("second".into(), "lul".into()), ].into_iter() .collect(); let non_empty_map = NonEmptyHashMap::from_std_hashmap(map); assert!(non_empty_map.is_some()); let empty_map: HashMap<String, String> = HashMap::new(); let non_empty_map = NonEmptyHashMap::from_std_hashmap(empty_map); // It is entirely impossible (hail to the type system!) to create an instance of the // `NonEmptyHashMap` with an empty map! assert!(non_empty_map.is_none()); }
And that's it! Yes, it is that simple.
If you'd like to implement the trait for your custom collections, have a look at the source
code of the crate (btree_map.rs
, hash_set.rs
, vec.rs
and so forth), or take a look at an
example in the examples
directory where we implement the trait for a "foreign" type.
Traits
TakeSome |
A helper trait that allows to take some value out of a collection, i.e. remove a single element and return it, while preserving all others. |