kanidmd_lib/valueset/
binary.rs
1use crate::prelude::*;
2use crate::schema::SchemaAttribute;
3use crate::utils::trigraph_iter;
4use crate::valueset::ScimResolveStatus;
5use crate::valueset::{DbValueSetV2, ValueSet};
6use base64urlsafedata::Base64UrlSafeData;
7use kanidm_proto::scim_v1::server::ScimBinary;
8use smolset::SmolSet;
9use std::collections::btree_map::Entry as BTreeEntry;
10use std::collections::BTreeMap;
11
12#[derive(Debug, Clone)]
13pub struct ValueSetPrivateBinary {
14 set: SmolSet<[Vec<u8>; 1]>,
15}
16
17impl ValueSetPrivateBinary {
18 pub fn new(b: Vec<u8>) -> Box<Self> {
19 let mut set = SmolSet::new();
20 set.insert(b);
21 Box::new(ValueSetPrivateBinary { set })
22 }
23
24 pub fn push(&mut self, b: Vec<u8>) -> bool {
25 self.set.insert(b)
26 }
27
28 pub fn from_dbvs2(data: Vec<Vec<u8>>) -> Result<ValueSet, OperationError> {
29 let set = data.into_iter().collect();
30 Ok(Box::new(ValueSetPrivateBinary { set }))
31 }
32
33 pub fn from_repl_v1(data: &[Base64UrlSafeData]) -> Result<ValueSet, OperationError> {
34 let set = data.iter().map(|b| b.to_vec()).collect();
35 Ok(Box::new(ValueSetPrivateBinary { set }))
36 }
37
38 #[allow(clippy::should_implement_trait)]
41 pub fn from_iter<T>(iter: T) -> Option<Box<ValueSetPrivateBinary>>
42 where
43 T: IntoIterator<Item = Vec<u8>>,
44 {
45 let set = iter.into_iter().collect();
46 Some(Box::new(ValueSetPrivateBinary { set }))
47 }
48}
49
50impl ValueSetT for ValueSetPrivateBinary {
51 fn insert_checked(&mut self, value: Value) -> Result<bool, OperationError> {
52 match value {
53 Value::PrivateBinary(u) => Ok(self.set.insert(u)),
54 _ => {
55 debug_assert!(false);
56 Err(OperationError::InvalidValueState)
57 }
58 }
59 }
60
61 fn clear(&mut self) {
62 self.set.clear();
63 }
64
65 fn remove(&mut self, _pv: &PartialValue, _cid: &Cid) -> bool {
66 true
67 }
68
69 fn contains(&self, _pv: &PartialValue) -> bool {
70 false
71 }
72
73 fn substring(&self, _pv: &PartialValue) -> bool {
74 false
75 }
76
77 fn startswith(&self, _pv: &PartialValue) -> bool {
78 false
79 }
80
81 fn endswith(&self, _pv: &PartialValue) -> bool {
82 false
83 }
84
85 fn lessthan(&self, _pv: &PartialValue) -> bool {
86 false
87 }
88
89 fn len(&self) -> usize {
90 self.set.len()
91 }
92
93 fn generate_idx_eq_keys(&self) -> Vec<String> {
94 Vec::with_capacity(0)
95 }
96
97 fn syntax(&self) -> SyntaxType {
98 SyntaxType::PrivateBinary
99 }
100
101 fn validate(&self, _schema_attr: &SchemaAttribute) -> bool {
102 true
103 }
104
105 fn to_proto_string_clone_iter(&self) -> Box<dyn Iterator<Item = String> + '_> {
106 Box::new(self.set.iter().map(|_| "private_binary".to_string()))
107 }
108
109 fn to_scim_value(&self) -> Option<ScimResolveStatus> {
110 None
111 }
112
113 fn to_db_valueset_v2(&self) -> DbValueSetV2 {
114 DbValueSetV2::PrivateBinary(self.set.iter().cloned().collect())
115 }
116
117 fn to_partialvalue_iter(&self) -> Box<dyn Iterator<Item = PartialValue> + '_> {
118 Box::new(
119 self.set
120 .iter()
121 .cloned()
122 .map(|_| PartialValue::PrivateBinary),
123 )
124 }
125
126 fn to_value_iter(&self) -> Box<dyn Iterator<Item = Value> + '_> {
127 Box::new(self.set.iter().cloned().map(Value::PrivateBinary))
128 }
129
130 fn equal(&self, other: &ValueSet) -> bool {
131 if let Some(other) = other.as_private_binary_set() {
132 &self.set == other
133 } else {
134 debug_assert!(false);
135 false
136 }
137 }
138
139 fn merge(&mut self, other: &ValueSet) -> Result<(), OperationError> {
140 if let Some(b) = other.as_private_binary_set() {
141 mergesets!(self.set, b)
142 } else {
143 debug_assert!(false);
144 Err(OperationError::InvalidValueState)
145 }
146 }
147
148 fn to_private_binary_single(&self) -> Option<&[u8]> {
149 if self.set.len() == 1 {
150 self.set.iter().map(|b| b.as_slice()).take(1).next()
151 } else {
152 None
153 }
154 }
155
156 fn as_private_binary_set(&self) -> Option<&SmolSet<[Vec<u8>; 1]>> {
157 Some(&self.set)
158 }
159}
160
161#[derive(Debug, Clone)]
162pub struct ValueSetPublicBinary {
163 map: BTreeMap<String, Vec<u8>>,
164}
165
166impl ValueSetPublicBinary {
167 pub fn new(t: String, b: Vec<u8>) -> Box<Self> {
168 let mut map = BTreeMap::new();
169 map.insert(t, b);
170 Box::new(ValueSetPublicBinary { map })
171 }
172
173 pub fn push(&mut self, t: String, b: Vec<u8>) -> bool {
174 self.map.insert(t, b).is_none()
175 }
176
177 pub fn from_dbvs2(data: Vec<(String, Vec<u8>)>) -> Result<ValueSet, OperationError> {
178 let map = data.into_iter().collect();
179 Ok(Box::new(ValueSetPublicBinary { map }))
180 }
181
182 #[allow(clippy::should_implement_trait)]
185 pub fn from_iter<T>(iter: T) -> Option<Box<ValueSetPublicBinary>>
186 where
187 T: IntoIterator<Item = (String, Vec<u8>)>,
188 {
189 let map = iter.into_iter().collect();
190 Some(Box::new(ValueSetPublicBinary { map }))
191 }
192}
193
194impl ValueSetT for ValueSetPublicBinary {
195 fn insert_checked(&mut self, value: Value) -> Result<bool, OperationError> {
196 match value {
197 Value::PublicBinary(t, b) => {
198 if let BTreeEntry::Vacant(e) = self.map.entry(t) {
199 e.insert(b);
200 Ok(true)
201 } else {
202 Ok(false)
203 }
204 }
205 _ => Err(OperationError::InvalidValueState),
206 }
207 }
208
209 fn clear(&mut self) {
210 self.map.clear();
211 }
212
213 fn remove(&mut self, pv: &PartialValue, _cid: &Cid) -> bool {
214 match pv {
215 PartialValue::PublicBinary(t) => self.map.remove(t.as_str()).is_some(),
216 _ => false,
217 }
218 }
219
220 fn contains(&self, pv: &PartialValue) -> bool {
221 match pv {
222 PartialValue::PublicBinary(t) => self.map.contains_key(t.as_str()),
223 _ => false,
224 }
225 }
226
227 fn substring(&self, _pv: &PartialValue) -> bool {
228 false
229 }
230
231 fn startswith(&self, _pv: &PartialValue) -> bool {
232 false
233 }
234
235 fn endswith(&self, _pv: &PartialValue) -> bool {
236 false
237 }
238
239 fn lessthan(&self, _pv: &PartialValue) -> bool {
240 false
241 }
242
243 fn len(&self) -> usize {
244 self.map.len()
245 }
246
247 fn generate_idx_eq_keys(&self) -> Vec<String> {
248 self.map.keys().cloned().collect()
249 }
250
251 fn generate_idx_sub_keys(&self) -> Vec<String> {
252 let lower: Vec<_> = self.map.keys().map(|s| s.to_lowercase()).collect();
253 let mut trigraphs: Vec<_> = lower.iter().flat_map(|v| trigraph_iter(v)).collect();
254
255 trigraphs.sort_unstable();
256 trigraphs.dedup();
257
258 trigraphs.into_iter().map(String::from).collect()
259 }
260
261 fn syntax(&self) -> SyntaxType {
262 unreachable!()
267 }
268
269 fn validate(&self, _schema_attr: &SchemaAttribute) -> bool {
270 self.map
271 .iter()
272 .all(|(s, _)| Value::validate_str_escapes(s) && Value::validate_singleline(s))
273 }
274
275 fn to_proto_string_clone_iter(&self) -> Box<dyn Iterator<Item = String> + '_> {
276 Box::new(self.map.keys().cloned())
277 }
278
279 fn to_scim_value(&self) -> Option<ScimResolveStatus> {
280 Some(ScimResolveStatus::Resolved(ScimValueKanidm::from(
281 self.map
282 .iter()
283 .map(|(tag, bin)| ScimBinary {
284 label: tag.clone(),
285 value: bin.clone(),
286 })
287 .collect::<Vec<_>>(),
288 )))
289 }
290
291 fn to_db_valueset_v2(&self) -> DbValueSetV2 {
292 DbValueSetV2::PublicBinary(
293 self.map
294 .iter()
295 .map(|(tag, bin)| (tag.clone(), bin.clone()))
296 .collect(),
297 )
298 }
299
300 fn to_partialvalue_iter(&self) -> Box<dyn Iterator<Item = PartialValue> + '_> {
301 Box::new(self.map.keys().cloned().map(PartialValue::PublicBinary))
302 }
303
304 fn to_value_iter(&self) -> Box<dyn Iterator<Item = Value> + '_> {
305 Box::new(
306 self.map
307 .iter()
308 .map(|(t, b)| Value::PublicBinary(t.clone(), b.clone())),
309 )
310 }
311
312 fn equal(&self, other: &ValueSet) -> bool {
313 if let Some(other) = other.as_publicbinary_map() {
314 &self.map == other
315 } else {
316 debug_assert!(false);
317 false
318 }
319 }
320
321 fn merge(&mut self, other: &ValueSet) -> Result<(), OperationError> {
322 if let Some(b) = other.as_publicbinary_map() {
323 mergemaps!(self.map, b)
324 } else {
325 debug_assert!(false);
326 Err(OperationError::InvalidValueState)
327 }
328 }
329
330 fn as_publicbinary_map(&self) -> Option<&BTreeMap<String, Vec<u8>>> {
331 Some(&self.map)
332 }
333}
334
335#[cfg(test)]
336mod tests {
337 use super::ValueSetPrivateBinary;
338 use crate::prelude::ValueSet;
339
340 #[test]
341 fn test_scim_private_binary() {
342 let vs: ValueSet = ValueSetPrivateBinary::new(vec![0x00]);
343
344 assert!(vs.to_scim_value().is_none());
345 }
346}