collect_once_hashmap/
btreemap.rs1use std::cmp::Ord;
2use std::collections::BTreeMap;
3use std::fmt::Debug;
4use std::hash::Hash;
5use std::iter::FromIterator;
6use std::iter::IntoIterator;
7
8#[derive(Debug, thiserror::Error)]
9pub enum Error<K>
10 where K: Debug,
11{
12 #[error("duplicated key in iterator: {:?}", _0)]
13 DuplicatedKey(K),
14
15 #[error("unknown error")]
16 Unknown,
17}
18
19pub struct CollectOnceBTreeMap<K, V>
20 where K: Eq + Ord + Hash + Debug
21{
22 inner: std::result::Result<BTreeMap<K, V>, Error<K>>
23}
24
25impl<K, V> CollectOnceBTreeMap<K, V>
26 where K: Eq + Ord + Hash + Debug
27{
28 pub fn into_inner(self) -> std::result::Result<BTreeMap<K, V>, Error<K>> {
29 self.inner
30 }
31}
32
33impl<K, V> FromIterator<(K, V)> for CollectOnceBTreeMap<K, V>
34 where K: Eq + Ord + Hash + Debug
35{
36 fn from_iter<T>(iter: T) -> Self
37 where T: IntoIterator<Item = (K, V)>
38 {
39 let mut hm = BTreeMap::new();
40
41 for (element_key, element_value) in iter.into_iter() {
42 if hm.contains_key(&element_key) {
43 return CollectOnceBTreeMap {
44 inner: Err(Error::DuplicatedKey(element_key))
45 }
46 } else {
47 hm.insert(element_key, element_value);
48 }
49 }
50
51 CollectOnceBTreeMap {
52 inner: Ok(hm)
53 }
54 }
55}
56
57
58#[cfg(test)]
59mod tests {
60 use super::CollectOnceBTreeMap;
61 use super::Error;
62
63 #[test]
64 fn test_empty() {
65 let hm = vec![]
66 .into_iter()
67 .collect::<CollectOnceBTreeMap<u8, u8>>()
68 .into_inner()
69 .unwrap();
70
71 assert_eq!(0, hm.keys().count());
72 }
73
74 #[test]
75 fn test_simple() {
76 let hm = vec![(1, 1)]
77 .into_iter()
78 .collect::<CollectOnceBTreeMap<u8, u8>>()
79 .into_inner()
80 .unwrap();
81
82 assert_eq!(1, hm.keys().count());
83 assert!(hm.contains_key(&1));
84 assert!(hm.keys().all(|k| *k == 1));
85 assert!(hm.values().all(|k| *k == 1));
86 }
87
88 #[test]
89 fn test_duplicate() {
90 let hm = vec![(1, 1), (1, 2)]
91 .into_iter()
92 .collect::<CollectOnceBTreeMap<u8, u8>>()
93 .into_inner();
94
95 assert!(hm.is_err());
96 assert!(std::matches!(hm, Err(Error::DuplicatedKey(1))));
97 }
98}
99