kanidmd_lib/valueset/
spn.rs
1use crate::prelude::*;
2use crate::schema::SchemaAttribute;
3use crate::valueset::{DbValueSetV2, ScimResolveStatus, ValueSet};
4
5use smolset::SmolSet;
6
7#[derive(Debug, Clone)]
8pub struct ValueSetSpn {
9 set: SmolSet<[(String, String); 1]>,
10}
11
12impl ValueSetSpn {
13 pub fn new(u: (String, String)) -> Box<Self> {
14 let mut set = SmolSet::new();
15 set.insert(u);
16 Box::new(ValueSetSpn { set })
17 }
18
19 pub fn push(&mut self, u: (String, String)) -> bool {
20 self.set.insert(u)
21 }
22
23 pub fn from_dbvs2(data: Vec<(String, String)>) -> Result<ValueSet, OperationError> {
24 let set = data.into_iter().collect();
25 Ok(Box::new(ValueSetSpn { set }))
26 }
27
28 #[allow(clippy::should_implement_trait)]
31 pub fn from_iter<T>(iter: T) -> Option<Box<Self>>
32 where
33 T: IntoIterator<Item = (String, String)>,
34 {
35 let set = iter.into_iter().collect();
36 Some(Box::new(ValueSetSpn { set }))
37 }
38}
39
40impl ValueSetT for ValueSetSpn {
41 fn insert_checked(&mut self, value: Value) -> Result<bool, OperationError> {
42 match value {
43 Value::Spn(n, d) => Ok(self.set.insert((n, d))),
44 _ => {
45 debug_assert!(false);
46 Err(OperationError::InvalidValueState)
47 }
48 }
49 }
50
51 fn clear(&mut self) {
52 self.set.clear();
53 }
54
55 fn remove(&mut self, pv: &PartialValue, _cid: &Cid) -> bool {
56 match pv {
57 PartialValue::Spn(n, d) => self.set.remove(&(n.clone(), d.clone())),
58 _ => {
59 debug_assert!(false);
60 true
61 }
62 }
63 }
64
65 fn contains(&self, pv: &PartialValue) -> bool {
66 match pv {
67 PartialValue::Spn(n, d) => self.set.contains(&(n.clone(), d.clone())),
68 _ => false,
69 }
70 }
71
72 fn substring(&self, _pv: &PartialValue) -> bool {
73 false
74 }
75
76 fn startswith(&self, _pv: &PartialValue) -> bool {
77 false
78 }
79
80 fn endswith(&self, _pv: &PartialValue) -> bool {
81 false
82 }
83
84 fn lessthan(&self, _pv: &PartialValue) -> bool {
85 false
86 }
87
88 fn len(&self) -> usize {
89 self.set.len()
90 }
91
92 fn generate_idx_eq_keys(&self) -> Vec<String> {
93 self.set.iter().map(|(n, d)| format!("{n}@{d}")).collect()
94 }
95
96 fn syntax(&self) -> SyntaxType {
97 SyntaxType::SecurityPrincipalName
98 }
99
100 fn validate(&self, _schema_attr: &SchemaAttribute) -> bool {
101 self.set.iter().all(|(a, b)| {
102 Value::validate_str_escapes(a)
103 && Value::validate_str_escapes(b)
104 && Value::validate_singleline(a)
105 && Value::validate_singleline(b)
106 })
107 }
108
109 fn to_proto_string_clone_iter(&self) -> Box<dyn Iterator<Item = String> + '_> {
110 Box::new(self.set.iter().map(|(n, d)| format!("{n}@{d}")))
111 }
112
113 fn to_scim_value(&self) -> Option<ScimResolveStatus> {
114 let mut iter = self.set.iter().map(|(n, d)| format!("{n}@{d}"));
115 if self.len() == 1 {
116 let v = iter.next().unwrap_or_default();
117 Some(v.into())
118 } else {
119 let arr = iter.collect::<Vec<_>>();
120 Some(arr.into())
121 }
122 }
123
124 fn to_db_valueset_v2(&self) -> DbValueSetV2 {
125 DbValueSetV2::Spn(self.set.iter().cloned().collect())
126 }
127
128 fn to_partialvalue_iter(&self) -> Box<dyn Iterator<Item = PartialValue> + '_> {
129 Box::new(
130 self.set
131 .iter()
132 .map(|(n, d)| PartialValue::Spn(n.clone(), d.clone())),
133 )
134 }
135
136 fn to_value_iter(&self) -> Box<dyn Iterator<Item = Value> + '_> {
137 Box::new(
138 self.set
139 .iter()
140 .map(|(n, d)| Value::Spn(n.clone(), d.clone())),
141 )
142 }
143
144 fn equal(&self, other: &ValueSet) -> bool {
145 if let Some(other) = other.as_spn_set() {
146 &self.set == other
147 } else {
148 debug_assert!(false);
149 false
150 }
151 }
152
153 fn merge(&mut self, other: &ValueSet) -> Result<(), OperationError> {
154 if let Some(b) = other.as_spn_set() {
155 mergesets!(self.set, b)
156 } else {
157 debug_assert!(false);
158 Err(OperationError::InvalidValueState)
159 }
160 }
161
162 fn as_spn_set(&self) -> Option<&SmolSet<[(String, String); 1]>> {
173 Some(&self.set)
174 }
175
176 }
182
183#[cfg(test)]
184mod tests {
185 use super::ValueSetSpn;
186 use crate::prelude::ValueSet;
187
188 #[test]
189 fn test_scim_spn() {
190 let vs: ValueSet = ValueSetSpn::new(("claire".to_string(), "example.com".to_string()));
191 crate::valueset::scim_json_reflexive(&vs, r#""claire@example.com""#);
192 }
193}