# take-some A simple library that provides a way to obtain *some* value from various collections. [![pipeline status](https://gitlab.com/mexus/take-some-rs/badges/master/pipeline.svg)](https://gitlab.com/mexus/take-some-rs/commits/master) [![crates.io](https://img.shields.io/crates/v/take-some.svg)](https://crates.io/crates/take-some) [![docs.rs](https://docs.rs/take-some/badge.svg)](https://docs.rs/take-some) [[Release docs]](https://docs.rs/take-some/) [[Master docs]](https://mexus.gitlab.io/take-some-rs/take_some/) 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), ::std::collections::HashMap))`. 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! ```rust extern crate take_some; use std::collections::HashMap; use std::hash::{BuildHasher, Hash}; use take_some::TakeSome; struct NonEmptyHashMap { first: (K, V), rest: HashMap, } impl NonEmptyHashMap where K: Eq + Hash, S: BuildHasher, { fn from_std_hashmap(mut map: HashMap) -> Option { 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) -> Option { map.split_at_some() .map(|(first, rest)| NonEmptyHashMap { first, rest }) .ok() } } fn main() { let map: HashMap = 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 = 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. License: MIT/Apache-2.0