use super::is_empty::IsEmpty;
pub trait EmptyIntoNone {
fn empty_into_none(self) -> Self;
}
impl<T> EmptyIntoNone for Option<T>
where
T: IsEmpty,
{
fn empty_into_none(self) -> Self {
self.and_then(|col| (!col.is_empty()).then(|| col))
}
}
#[cfg(test)]
mod test {
use std::collections::{
BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque,
};
use maplit::*;
use super::EmptyIntoNone;
fn check<C>(col: Option<C>, should_be_some: bool)
where
C: crate::is_empty::IsEmpty + std::fmt::Debug + Clone,
{
let into_none = col.clone().empty_into_none();
if should_be_some {
assert!(
into_none.is_some(),
"Should be Some: {:?}.empty_into_none()\n\
Got: {:?}",
col,
into_none,
);
} else {
assert!(
into_none.is_none(),
"Should be None: {:?}.empty_into_none()\n\
Got: {:?}",
col,
into_none,
);
}
}
#[test]
fn binary_heap() {
let mut bh = BinaryHeap::<&str>::new();
bh.push("a");
check(Some(bh.clone()), true);
bh.push("b");
bh.push("c");
check(Some(bh), true);
check(Some(BinaryHeap::<&str>::new()), false);
check(Option::<BinaryHeap<&str>>::None, false);
}
#[test]
fn btree_map() {
check(Some(btreemap! {"a" => 1}), true);
check(Some(btreemap! {"a" => 1, "b" => 2, "c" => 3}), true);
check(Some(BTreeMap::<&str, i8>::new()), false);
check(Option::<BTreeMap<&str, i8>>::None, false);
}
#[test]
fn btree_set() {
check(Some(btreeset! {"a"}), true);
check(Some(btreeset! {"a", "b", "c"}), true);
check(Some(BTreeSet::<&str>::new()), false);
check(Option::<BTreeSet<&str>>::None, false);
}
#[test]
fn hash_map() {
check(Some(hashmap! {"a" => 1}), true);
check(Some(hashmap! {"a" => 1, "b" => 2, "c" => 3}), true);
check(Some(HashMap::<&str, i8>::new()), false);
check(Option::<HashMap<&str, i8>>::None, false);
}
#[test]
fn hash_set() {
check(Some(hashset! {"a"}), true);
check(Some(hashset! {"a", "b", "c"}), true);
check(Some(HashSet::<&str>::new()), false);
check(Option::<HashSet<&str>>::None, false);
}
#[test]
fn linked_list() {
let mut ll = LinkedList::new();
ll.push_back("a");
check(Some(ll.clone()), true);
ll.push_back("b");
ll.push_back("c");
check(Some(ll), true);
check(Some(LinkedList::<&str>::new()), false);
check(Option::<LinkedList<&str>>::None, false);
}
#[test]
fn vec() {
check(Some(vec!["a"]), true);
check(Some(vec!["a", "b", "c"]), true);
check(Some(Vec::<&str>::new()), false);
check(Option::<Vec<&str>>::None, false);
}
#[test]
fn vec_deque() {
check(Some(VecDeque::from(vec!["a"])), true);
check(Some(VecDeque::from(vec!["a", "b", "c"])), true);
check(Some(VecDeque::<&str>::new()), false);
check(Option::<VecDeque<&str>>::None, false);
}
#[test]
fn string() {
check(Some(String::from("a")), true);
check(Some(String::new()), false);
check(Option::<String>::None, false);
}
#[test]
fn str() {
check(Some("a"), true);
check(Some(""), false);
check(Option::<String>::None, false);
}
#[test]
fn slice() {
check(Some("a".as_bytes()), true);
check(Some("".as_bytes()), false);
check(Option::<&[u8]>::None, false);
}
}