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