cliquenet/util/
nonempty.rs1use std::{collections::BTreeMap, iter::once};
2
3#[derive(Debug)]
5pub(crate) struct NonEmpty<T: Container>(T::Element, T);
6
7pub(crate) trait Container {
8 type Element;
9}
10
11impl<A> Container for Vec<A> {
12 type Element = A;
13}
14
15impl<K: Ord, V> Container for BTreeMap<K, V> {
16 type Element = (K, V);
17}
18
19impl<A> NonEmpty<Vec<A>> {
20 pub(crate) fn new<I>(fst: A, rest: I) -> Self
21 where
22 I: IntoIterator<Item = A>,
23 {
24 Self(fst, rest.into_iter().collect())
25 }
26
27 pub(crate) fn assert_non_empty_vec<I>(it: I) -> Self
28 where
29 I: IntoIterator<Item = A>,
30 {
31 let mut it = it.into_iter();
32 let fst = it.next().expect("non empty vector");
33 Self(fst, it.collect())
34 }
35
36 pub(crate) fn last(&self) -> &A {
37 self.1.as_slice().last().unwrap_or(&self.0)
38 }
39
40 pub(crate) fn get(&self, i: usize) -> Option<&A> {
41 match i {
42 0 => Some(&self.0),
43 _ => self.1.get(i - 1),
44 }
45 }
46
47 pub(crate) fn iter(&self) -> impl Iterator<Item = &A> {
48 once(&self.0).chain(self.1.as_slice().iter())
49 }
50}
51
52impl<K: Ord, V> NonEmpty<BTreeMap<K, V>> {
53 pub(crate) fn assert_non_empty_map<I>(it: I) -> Self
54 where
55 I: IntoIterator<Item = (K, V)>,
56 {
57 let mut m = BTreeMap::from_iter(it);
58 let fst = m.pop_first().expect("non empty map");
59 Self(fst, m)
60 }
61
62 pub(crate) fn first(&self) -> (&K, &V) {
63 (&self.0.0, &self.0.1)
64 }
65
66 pub(crate) fn last(&self) -> (&K, &V) {
67 self.1.last_key_value().unwrap_or((&self.0.0, &self.0.1))
68 }
69
70 pub(crate) fn get(&self, k: &K) -> Option<&V> {
71 (&self.0.0 == k)
72 .then_some(&self.0.1)
73 .or_else(|| self.1.get(k))
74 }
75
76 pub(crate) fn iter(&self) -> impl Iterator<Item = (&K, &V)> {
77 once((&self.0.0, &self.0.1)).chain(self.1.iter())
78 }
79}