cipherstash_config/
list.rs1use serde::{
2 de::{Deserialize, Deserializer, Visitor},
3 ser::{Serialize, SerializeSeq},
4};
5use std::fmt::Debug;
6use thiserror::Error;
7
8#[derive(Debug, Error)]
9#[error("Cannot insert duplicate entry to list: `{0:?}`")]
10pub struct DuplicateEntry<E: ListEntry>(E);
11
12pub trait ListEntry: PartialEq + Debug + Clone {}
13
14#[derive(Debug, Clone, PartialEq, Eq)]
15pub struct UniqueList<E: ListEntry> {
16 items: Vec<E>,
17}
18
19impl<E: ListEntry> Default for UniqueList<E> {
20 fn default() -> Self {
21 Self { items: vec![] }
22 }
23}
24
25impl<E: ListEntry> UniqueList<E> {
26 pub fn new() -> Self {
27 Self { items: vec![] }
28 }
29
30 pub fn with_capacity(size: usize) -> Self {
31 Self {
32 items: Vec::with_capacity(size),
33 }
34 }
35
36 pub fn try_insert(&mut self, entry: E) -> Result<(), DuplicateEntry<E>> {
37 if self.has_entry(&entry) {
38 Err(DuplicateEntry(entry))
39 } else {
40 self.items.push(entry);
41 Ok(())
42 }
43 }
44
45 pub fn has_entry<Q>(&self, query: &Q) -> bool
46 where
47 E: PartialEq<Q>,
48 {
49 self.get(query).is_some()
50 }
51
52 pub fn get<Q>(&self, query: &Q) -> Option<&E>
53 where
54 E: PartialEq<Q>,
55 {
56 if let Some(e) = self.items.iter().find(|e: &&E| *e == query) {
57 Some(e)
58 } else {
59 None
60 }
61 }
62
63 pub fn iter(&self) -> std::slice::Iter<'_, E> {
64 self.items.iter()
65 }
66
67 pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, E> {
68 self.items.iter_mut()
69 }
70
71 pub fn len(&self) -> usize {
72 self.items.len()
73 }
74
75 pub fn is_empty(&self) -> bool {
76 self.items.is_empty()
77 }
78}
79
80impl<E: ListEntry> std::ops::Index<usize> for UniqueList<E> {
81 type Output = E;
82
83 fn index(&self, i: usize) -> &Self::Output {
84 &self.items[i]
85 }
86}
87
88impl<E: ListEntry> Serialize for UniqueList<E>
89where
90 E: Serialize,
91{
92 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
93 where
94 S: serde::Serializer,
95 {
96 let mut seq = serializer.serialize_seq(Some(self.items.len()))?;
97
98 for element in self.items.iter() {
99 seq.serialize_element(element)?;
100 }
101
102 seq.end()
103 }
104}
105
106struct UniqueListDeserializer<E>(std::marker::PhantomData<E>);
107
108impl<E> UniqueListDeserializer<E> {
109 fn new() -> Self {
110 Self(Default::default())
111 }
112}
113
114impl<'de, E: ListEntry + Deserialize<'de>> Visitor<'de> for UniqueListDeserializer<E> {
115 type Value = UniqueList<E>;
116
117 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
118 write!(formatter, "a unique list of values")
119 }
120
121 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
122 where
123 A: serde::de::SeqAccess<'de>,
124 {
125 let mut list = seq
126 .size_hint()
127 .map(Self::Value::with_capacity)
128 .unwrap_or_else(Self::Value::new);
129
130 while let Some(value) = seq.next_element::<E>()? {
131 list.try_insert(value).map_err(serde::de::Error::custom)?;
132 }
133
134 Ok(list)
135 }
136}
137
138impl<'de, E: ListEntry> Deserialize<'de> for UniqueList<E>
139where
140 E: Deserialize<'de>,
141{
142 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
143 where
144 D: Deserializer<'de>,
145 {
146 deserializer.deserialize_seq(UniqueListDeserializer::<E>::new())
147 }
148}
149
150#[cfg(test)]
151mod tests {
152 use super::*;
153 use serde_json::{from_str, to_string};
154
155 impl ListEntry for usize {}
156
157 #[derive(Clone, PartialEq, Debug)]
158 struct MyEntry(u32, u32);
159 impl ListEntry for MyEntry {}
160
161 #[test]
162 fn empty_has_key() -> Result<(), Box<dyn std::error::Error>> {
163 let list: UniqueList<MyEntry> = UniqueList::new();
164 assert!(!list.has_entry(&MyEntry(10, 10)));
165
166 Ok(())
167 }
168
169 #[test]
170 fn empty_get() -> Result<(), Box<dyn std::error::Error>> {
171 let list: UniqueList<MyEntry> = UniqueList::new();
172 assert_eq!(list.get(&MyEntry(1, 1)), None);
173
174 Ok(())
175 }
176
177 #[test]
178 fn insert_dupe() -> Result<(), Box<dyn std::error::Error>> {
179 let mut list: UniqueList<MyEntry> = UniqueList::new();
180 list.try_insert(MyEntry(10, 10))?;
181 assert!(list.try_insert(MyEntry(10, 10)).is_err());
182
183 Ok(())
184 }
185
186 #[test]
187 fn insert_and_get() -> Result<(), Box<dyn std::error::Error>> {
188 let mut list: UniqueList<MyEntry> = UniqueList::new();
189 list.try_insert(MyEntry(5, 15))?;
190 let result = list.get(&MyEntry(5, 15));
191 assert_eq!(result, Some(&MyEntry(5, 15)));
192
193 Ok(())
194 }
195
196 #[test]
197 fn test_serialise_with_serde() -> Result<(), Box<dyn std::error::Error>> {
198 let mut list = UniqueList::<usize>::new();
199
200 list.try_insert(40)?;
201 list.try_insert(10)?;
202 list.try_insert(20)?;
203 list.try_insert(30)?;
204
205 assert_eq!(to_string(&list)?, "[40,10,20,30]");
206
207 Ok(())
208 }
209
210 #[test]
211 fn test_deserialise_with_serde() -> Result<(), Box<dyn std::error::Error>> {
212 let mut list = UniqueList::<usize>::new();
213 list.try_insert(40)?;
214 list.try_insert(10)?;
215 list.try_insert(20)?;
216 list.try_insert(30)?;
217
218 assert_eq!(from_str::<UniqueList<usize>>("[40,10,20,30]")?, list);
219
220 Ok(())
221 }
222
223 #[test]
224 fn test_fail_deserialise_with_serde() -> Result<(), Box<dyn std::error::Error>> {
225 assert_eq!(
226 from_str::<UniqueList<usize>>("[10,10,10,10]")
227 .expect_err("Expected de to fail")
228 .to_string(),
229 "Cannot insert duplicate entry to list: `10` at line 1 column 7"
230 );
231
232 Ok(())
233 }
234}