kanidmd_lib/valueset/
binary.rs1use 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(self.set.iter().map(|_| PartialValue::PrivateBinary))
119 }
120
121 fn to_value_iter(&self) -> Box<dyn Iterator<Item = Value> + '_> {
122 Box::new(self.set.iter().cloned().map(Value::PrivateBinary))
123 }
124
125 fn equal(&self, other: &ValueSet) -> bool {
126 if let Some(other) = other.as_private_binary_set() {
127 &self.set == other
128 } else {
129 debug_assert!(false);
130 false
131 }
132 }
133
134 fn merge(&mut self, other: &ValueSet) -> Result<(), OperationError> {
135 if let Some(b) = other.as_private_binary_set() {
136 mergesets!(self.set, b)
137 } else {
138 debug_assert!(false);
139 Err(OperationError::InvalidValueState)
140 }
141 }
142
143 fn to_private_binary_single(&self) -> Option<&[u8]> {
144 if self.set.len() == 1 {
145 self.set.iter().map(|b| b.as_slice()).take(1).next()
146 } else {
147 None
148 }
149 }
150
151 fn as_private_binary_set(&self) -> Option<&SmolSet<[Vec<u8>; 1]>> {
152 Some(&self.set)
153 }
154}
155
156#[derive(Debug, Clone)]
157pub struct ValueSetPublicBinary {
158 map: BTreeMap<String, Vec<u8>>,
159}
160
161impl ValueSetPublicBinary {
162 pub fn new(t: String, b: Vec<u8>) -> Box<Self> {
163 let mut map = BTreeMap::new();
164 map.insert(t, b);
165 Box::new(ValueSetPublicBinary { map })
166 }
167
168 pub fn push(&mut self, t: String, b: Vec<u8>) -> bool {
169 self.map.insert(t, b).is_none()
170 }
171
172 pub fn from_dbvs2(data: Vec<(String, Vec<u8>)>) -> Result<ValueSet, OperationError> {
173 let map = data.into_iter().collect();
174 Ok(Box::new(ValueSetPublicBinary { map }))
175 }
176
177 #[allow(clippy::should_implement_trait)]
180 pub fn from_iter<T>(iter: T) -> Option<Box<ValueSetPublicBinary>>
181 where
182 T: IntoIterator<Item = (String, Vec<u8>)>,
183 {
184 let map = iter.into_iter().collect();
185 Some(Box::new(ValueSetPublicBinary { map }))
186 }
187}
188
189impl ValueSetT for ValueSetPublicBinary {
190 fn insert_checked(&mut self, value: Value) -> Result<bool, OperationError> {
191 match value {
192 Value::PublicBinary(t, b) => {
193 if let BTreeEntry::Vacant(e) = self.map.entry(t) {
194 e.insert(b);
195 Ok(true)
196 } else {
197 Ok(false)
198 }
199 }
200 _ => Err(OperationError::InvalidValueState),
201 }
202 }
203
204 fn clear(&mut self) {
205 self.map.clear();
206 }
207
208 fn remove(&mut self, pv: &PartialValue, _cid: &Cid) -> bool {
209 match pv {
210 PartialValue::PublicBinary(t) => self.map.remove(t.as_str()).is_some(),
211 _ => false,
212 }
213 }
214
215 fn contains(&self, pv: &PartialValue) -> bool {
216 match pv {
217 PartialValue::PublicBinary(t) => self.map.contains_key(t.as_str()),
218 _ => false,
219 }
220 }
221
222 fn substring(&self, _pv: &PartialValue) -> bool {
223 false
224 }
225
226 fn startswith(&self, _pv: &PartialValue) -> bool {
227 false
228 }
229
230 fn endswith(&self, _pv: &PartialValue) -> bool {
231 false
232 }
233
234 fn lessthan(&self, _pv: &PartialValue) -> bool {
235 false
236 }
237
238 fn len(&self) -> usize {
239 self.map.len()
240 }
241
242 fn generate_idx_eq_keys(&self) -> Vec<String> {
243 self.map.keys().cloned().collect()
244 }
245
246 fn generate_idx_sub_keys(&self) -> Vec<String> {
247 let lower: Vec<_> = self.map.keys().map(|s| s.to_lowercase()).collect();
248 let mut trigraphs: Vec<_> = lower.iter().flat_map(|v| trigraph_iter(v)).collect();
249
250 trigraphs.sort_unstable();
251 trigraphs.dedup();
252
253 trigraphs.into_iter().map(String::from).collect()
254 }
255
256 fn syntax(&self) -> SyntaxType {
257 unreachable!()
262 }
263
264 fn validate(&self, _schema_attr: &SchemaAttribute) -> bool {
265 self.map
266 .iter()
267 .all(|(s, _)| Value::validate_str_escapes(s) && Value::validate_singleline(s))
268 }
269
270 fn to_proto_string_clone_iter(&self) -> Box<dyn Iterator<Item = String> + '_> {
271 Box::new(self.map.keys().cloned())
272 }
273
274 fn to_scim_value(&self) -> Option<ScimResolveStatus> {
275 Some(ScimResolveStatus::Resolved(ScimValueKanidm::from(
276 self.map
277 .iter()
278 .map(|(tag, bin)| ScimBinary {
279 label: tag.clone(),
280 value: bin.clone(),
281 })
282 .collect::<Vec<_>>(),
283 )))
284 }
285
286 fn to_db_valueset_v2(&self) -> DbValueSetV2 {
287 DbValueSetV2::PublicBinary(
288 self.map
289 .iter()
290 .map(|(tag, bin)| (tag.clone(), bin.clone()))
291 .collect(),
292 )
293 }
294
295 fn to_partialvalue_iter(&self) -> Box<dyn Iterator<Item = PartialValue> + '_> {
296 Box::new(self.map.keys().cloned().map(PartialValue::PublicBinary))
297 }
298
299 fn to_value_iter(&self) -> Box<dyn Iterator<Item = Value> + '_> {
300 Box::new(
301 self.map
302 .iter()
303 .map(|(t, b)| Value::PublicBinary(t.clone(), b.clone())),
304 )
305 }
306
307 fn equal(&self, other: &ValueSet) -> bool {
308 if let Some(other) = other.as_publicbinary_map() {
309 &self.map == other
310 } else {
311 debug_assert!(false);
312 false
313 }
314 }
315
316 fn merge(&mut self, other: &ValueSet) -> Result<(), OperationError> {
317 if let Some(b) = other.as_publicbinary_map() {
318 mergemaps!(self.map, b)
319 } else {
320 debug_assert!(false);
321 Err(OperationError::InvalidValueState)
322 }
323 }
324
325 fn as_publicbinary_map(&self) -> Option<&BTreeMap<String, Vec<u8>>> {
326 Some(&self.map)
327 }
328}
329
330#[cfg(test)]
331mod tests {
332 use super::ValueSetPrivateBinary;
333 use crate::prelude::ValueSet;
334
335 #[test]
336 fn test_scim_private_binary() {
337 let vs: ValueSet = ValueSetPrivateBinary::new(vec![0x00]);
338
339 assert!(vs.to_scim_value().is_none());
340 }
341}