xapi_rs/data/
statement_ref.rs1use crate::{
4 data::{DataError, Fingerprint, ObjectType, Validate, ValidationError},
5 emit_error,
6};
7use core::fmt;
8use serde::{Deserialize, Serialize};
9use std::hash::{Hash, Hasher};
10use uuid::Uuid;
11
12#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
15pub struct StatementRef {
16 #[serde(rename = "objectType")]
17 object_type: ObjectType,
18 id: Uuid,
19}
20
21impl StatementRef {
22 pub fn builder() -> StatementRefBuilder {
24 StatementRefBuilder::default()
25 }
26
27 pub fn id(&self) -> &Uuid {
29 &self.id
30 }
31
32 pub fn check_object_type(&self) -> bool {
37 self.object_type == ObjectType::StatementRef
38 }
39}
40
41impl fmt::Display for StatementRef {
42 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43 write!(
44 f,
45 "StatementRef{{ id: \"{}\" }}",
46 self.id
47 .as_hyphenated()
48 .encode_lower(&mut Uuid::encode_buffer())
49 )
50 }
51}
52
53impl Fingerprint for StatementRef {
54 fn fingerprint<H: Hasher>(&self, state: &mut H) {
55 self.id.hash(state)
56 }
57}
58
59impl Validate for StatementRef {
60 fn validate(&self) -> Vec<ValidationError> {
61 let mut vec = vec![];
62
63 if !self.check_object_type() {
64 vec.push(ValidationError::WrongObjectType {
65 expected: ObjectType::StatementRef,
66 found: self.object_type.to_string().into(),
67 })
68 }
69 if self.id.is_max() || self.id.is_nil() {
70 vec.push(ValidationError::ConstraintViolation(
71 "ID should not be all 0's or 1's".into(),
72 ))
73 }
74
75 vec
76 }
77}
78
79#[derive(Debug, Default)]
81pub struct StatementRefBuilder {
82 _id: Option<Uuid>,
83}
84
85impl StatementRefBuilder {
86 pub fn id(mut self, val: &str) -> Result<Self, DataError> {
91 let val = val.trim();
92 if val.is_empty() {
93 emit_error!(DataError::Validation(ValidationError::Empty("id".into())))
94 } else {
95 let uuid = Uuid::parse_str(val)?;
96 if uuid.is_nil() || uuid.is_max() {
97 emit_error!(DataError::Validation(ValidationError::ConstraintViolation(
98 "'id' should not be all 0's or 1's".into()
99 )))
100 } else {
101 self._id = Some(uuid);
102 Ok(self)
103 }
104 }
105 }
106
107 pub fn id_as_uuid(mut self, uuid: Uuid) -> Result<Self, DataError> {
112 if uuid.is_nil() || uuid.is_max() {
113 emit_error!(DataError::Validation(ValidationError::ConstraintViolation(
114 "ID should not be all 0's or 1's".into()
115 )))
116 } else {
117 self._id = Some(uuid);
118 Ok(self)
119 }
120 }
121
122 pub fn build(&self) -> Result<StatementRef, DataError> {
126 if self._id.is_none() {
127 emit_error!(DataError::Validation(ValidationError::MissingField(
128 "id".into()
129 )))
130 } else {
131 Ok(StatementRef {
132 object_type: ObjectType::StatementRef,
133 id: self._id.unwrap(),
134 })
135 }
136 }
137}
138
139#[cfg(test)]
140mod tests {
141 use super::*;
142 use uuid::uuid;
143
144 const ID1: Uuid = uuid!("9e13cefd-53d3-4eac-b5ed-2cf6693903bb");
145 const ID2: Uuid = uuid!("9e13cefd53d34eacb5ed2cf6693903bb");
146 const JSON: &str =
147 r#"{"objectType":"StatementRef","id":"9e13cefd-53d3-4eac-b5ed-2cf6693903bb"}"#;
148
149 #[test]
150 fn test_serde_hyphenated_uuid() -> Result<(), DataError> {
151 let sr1 = StatementRef::builder().id_as_uuid(ID1)?.build()?;
152 let se_result = serde_json::to_string(&sr1);
153 assert!(se_result.is_ok());
154 let json = se_result.unwrap();
155 assert_eq!(json, JSON);
156
157 let de_result = serde_json::from_str::<StatementRef>(JSON);
158 assert!(de_result.is_ok());
159 let sr2 = de_result.unwrap();
160
161 assert_eq!(sr1, sr2);
162 assert!(sr1 == sr2);
163
164 let sr1 = StatementRef::builder()
167 .id("9e13cefd53d34eacb5ed2cf6693903bb")?
168 .build()?;
169 let se_result = serde_json::to_string(&sr1);
170 assert!(se_result.is_ok());
171 let json = se_result.unwrap();
172 assert_eq!(json, JSON);
173
174 let de_result = serde_json::from_str::<StatementRef>(JSON);
175 assert!(de_result.is_ok());
176 let sr2 = de_result.unwrap();
177
178 assert_eq!(sr1, sr2);
179
180 Ok(())
181 }
182
183 #[test]
184 fn test_serde_simple_uuid() -> Result<(), DataError> {
185 let sr1 = StatementRef::builder().id_as_uuid(ID2)?.build()?;
186 let se_result = serde_json::to_string(&sr1);
187 assert!(se_result.is_ok());
188 let json = se_result.unwrap();
189 assert_eq!(json, JSON);
190
191 let de_result = serde_json::from_str::<StatementRef>(JSON);
192 assert!(de_result.is_ok());
193 let sr2 = de_result.unwrap();
194
195 assert_eq!(sr1, sr2);
196
197 let sr1 = StatementRef::builder()
200 .id("9e13cefd-53d3-4eac-b5ed-2cf6693903bb")?
201 .build()?;
202 let se_result = serde_json::to_string(&sr1);
203 assert!(se_result.is_ok());
204 let json = se_result.unwrap();
205 assert_eq!(json, JSON);
206
207 let de_result = serde_json::from_str::<StatementRef>(JSON);
208 assert!(de_result.is_ok());
209 let sr2 = de_result.unwrap();
210
211 assert_eq!(sr1, sr2);
212
213 Ok(())
214 }
215
216 #[test]
217 fn test_uuid_as_hyphenated() -> Result<(), DataError> {
218 let uuid = ID2.as_hyphenated();
219 let sr1 = StatementRef::builder()
220 .id_as_uuid(uuid.into_uuid())?
221 .build()?;
222
223 let se_result = serde_json::to_string(&sr1);
224 assert!(se_result.is_ok());
225 let json = se_result.unwrap();
226 assert_eq!(json, JSON);
227
228 let de_result = serde_json::from_str::<StatementRef>(&json);
229 assert!(de_result.is_ok());
230 let sr2 = de_result.unwrap();
231
232 assert_eq!(sr1, sr2);
233
234 Ok(())
235 }
236
237 #[test]
238 fn test_uuid_fmt() -> Result<(), DataError> {
239 let sr1 = StatementRef::builder().id_as_uuid(ID1)?.build()?;
240
241 let hyphenated_uuid = ID1.as_hyphenated();
242 let sr2 = StatementRef::builder()
243 .id_as_uuid(hyphenated_uuid.into_uuid())?
244 .build()?;
245 assert_eq!(sr1, sr2);
246
247 let braced_uuid = ID1.as_braced();
248 let sr3 = StatementRef::builder()
249 .id_as_uuid(braced_uuid.into_uuid())?
250 .build()?;
251 assert_eq!(sr1, sr3);
252
253 let simple_uuid = ID1.as_simple();
254 let sr4 = StatementRef::builder()
255 .id_as_uuid(simple_uuid.into_uuid())?
256 .build()?;
257 assert_eq!(sr1, sr4);
258
259 let urn_uuid = ID1.as_urn();
260 let sr5 = StatementRef::builder()
261 .id_as_uuid(urn_uuid.into_uuid())?
262 .build()?;
263 assert_eq!(sr1, sr5);
264
265 Ok(())
266 }
267}