xapi_rs/data/
sub_statement_object.rs1use crate::data::{
4 Activity, ActivityId, Agent, AgentId, DataError, Fingerprint, Group, GroupId, StatementRef,
5 Validate, ValidationError,
6};
7use core::fmt;
8use serde::{Deserialize, Serialize, de::Error};
9use std::hash::Hasher;
10
11#[derive(Clone, Debug, PartialEq, Serialize)]
18#[serde(untagged)]
19pub enum SubStatementObject {
20 Agent(Agent),
22 Group(Group),
24 StatementRef(StatementRef),
26 Activity(Activity),
28}
29
30#[derive(Debug, Serialize)]
31#[serde(untagged)]
32pub(crate) enum SubStatementObjectId {
33 Activity(ActivityId),
34 Agent(AgentId),
35 Group(GroupId),
36 StatementRef(StatementRef),
37}
38
39impl From<SubStatementObject> for SubStatementObjectId {
40 fn from(value: SubStatementObject) -> Self {
41 match value {
42 SubStatementObject::Agent(agent) => SubStatementObjectId::Agent(agent.into()),
43 SubStatementObject::Group(group) => SubStatementObjectId::Group(group.into()),
44 SubStatementObject::StatementRef(stmt_ref) => {
45 SubStatementObjectId::StatementRef(stmt_ref)
46 }
47 SubStatementObject::Activity(activity) => {
48 SubStatementObjectId::Activity(activity.into())
49 }
50 }
51 }
52}
53
54impl From<SubStatementObjectId> for SubStatementObject {
55 fn from(value: SubStatementObjectId) -> Self {
56 match value {
57 SubStatementObjectId::Activity(x) => SubStatementObject::Activity(Activity::from(x)),
58 SubStatementObjectId::Agent(x) => SubStatementObject::Agent(Agent::from(x)),
59 SubStatementObjectId::Group(x) => SubStatementObject::Group(Group::from(x)),
60 SubStatementObjectId::StatementRef(x) => SubStatementObject::StatementRef(x),
61 }
62 }
63}
64
65impl SubStatementObject {
66 pub fn from_agent(obj: Agent) -> Self {
68 SubStatementObject::Agent(obj)
69 }
70
71 pub fn from_group(obj: Group) -> Self {
73 SubStatementObject::Group(obj)
74 }
75
76 pub fn from_statement_ref(obj: StatementRef) -> Self {
78 SubStatementObject::StatementRef(obj)
79 }
80
81 pub fn from_activity(obj: Activity) -> Self {
83 SubStatementObject::Activity(obj)
84 }
85
86 pub fn is_agent(&self) -> bool {
90 matches!(self, SubStatementObject::Agent(_))
91 }
92
93 pub fn is_group(&self) -> bool {
97 matches!(self, SubStatementObject::Group(_))
98 }
99
100 pub fn is_statement_ref(&self) -> bool {
104 matches!(self, SubStatementObject::StatementRef(_))
105 }
106
107 pub fn is_activity(&self) -> bool {
111 matches!(self, SubStatementObject::Activity(_))
112 }
113
114 pub fn as_agent(&self) -> Result<Agent, DataError> {
117 match self {
118 SubStatementObject::Agent(x) => Ok(x.to_owned()),
119 _ => Err(DataError::Validation(ValidationError::ConstraintViolation(
120 format!("This ({self}) is NOT an Agent").into(),
121 ))),
122 }
123 }
124
125 pub fn as_group(&self) -> Result<Group, DataError> {
128 match self {
129 SubStatementObject::Group(x) => Ok(x.to_owned()),
130 _ => Err(DataError::Validation(ValidationError::ConstraintViolation(
131 format!("This ({self}) is NOT a Group").into(),
132 ))),
133 }
134 }
135
136 pub fn as_statement_ref(&self) -> Result<StatementRef, DataError> {
139 match self {
140 SubStatementObject::StatementRef(x) => Ok(x.to_owned()),
141 _ => Err(DataError::Validation(ValidationError::ConstraintViolation(
142 format!("This ({self}) is NOT a StatementRef").into(),
143 ))),
144 }
145 }
146
147 pub fn as_activity(&self) -> Result<Activity, DataError> {
150 match self {
151 SubStatementObject::Activity(x) => Ok(x.to_owned()),
152 _ => Err(DataError::Validation(ValidationError::ConstraintViolation(
153 format!("This ({self}) is NOT an Activity").into(),
154 ))),
155 }
156 }
157}
158
159impl<'de> Deserialize<'de> for SubStatementObject {
160 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
161 where
162 D: serde::Deserializer<'de>,
163 {
164 let value = serde_json::Value::deserialize(deserializer)?;
165 if let Ok(x) = Agent::deserialize(value.clone())
166 && x.check_object_type()
167 {
168 return Ok(SubStatementObject::Agent(x));
169 }
170 if let Ok(x) = Group::deserialize(value.clone())
171 && x.check_object_type()
172 {
173 return Ok(SubStatementObject::Group(x));
174 }
175 if let Ok(x) = StatementRef::deserialize(value.clone())
176 && x.check_object_type()
177 {
178 return Ok(SubStatementObject::StatementRef(x));
179 }
180 match Activity::deserialize(value) {
181 Ok(x) => Ok(SubStatementObject::Activity(x)),
182 _ => Err(D::Error::custom(
183 "input did not match any SubStatementObject variant",
184 )),
185 }
186 }
187}
188
189impl fmt::Display for SubStatementObject {
190 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
191 match self {
192 SubStatementObject::Activity(x) => write!(f, "{x}"),
193 SubStatementObject::Agent(x) => write!(f, "{x}"),
194 SubStatementObject::Group(x) => write!(f, "{x}"),
195 SubStatementObject::StatementRef(x) => write!(f, "{x}"),
196 }
197 }
198}
199
200impl Fingerprint for SubStatementObject {
201 fn fingerprint<H: Hasher>(&self, state: &mut H) {
202 match self {
203 SubStatementObject::Agent(x) => x.fingerprint(state),
204 SubStatementObject::Group(x) => x.fingerprint(state),
205 SubStatementObject::StatementRef(x) => x.fingerprint(state),
206 SubStatementObject::Activity(x) => x.fingerprint(state),
207 }
208 }
209}
210
211impl Validate for SubStatementObject {
212 fn validate(&self) -> Vec<ValidationError> {
213 match self {
214 SubStatementObject::Activity(x) => x.validate(),
215 SubStatementObject::Agent(x) => x.validate(),
216 SubStatementObject::Group(x) => x.validate(),
217 SubStatementObject::StatementRef(x) => x.validate(),
218 }
219 }
220}
221
222#[cfg(test)]
223mod tests {
224 use super::*;
225 use tracing_test::traced_test;
226
227 const ID: &str = "9e13cefd-53d3-4eac-b5ed-2cf6693903bb";
228 const JSON: &str =
229 r#"{"objectType":"StatementRef","id":"9e13cefd-53d3-4eac-b5ed-2cf6693903bb"}"#;
230
231 #[traced_test]
232 #[test]
233 fn test_se() -> Result<(), DataError> {
234 let sr = StatementRef::builder().id(ID)?.build()?;
235 let sso = SubStatementObject::StatementRef(sr);
236 let se_result = serde_json::to_string(&sso);
237 assert!(se_result.is_ok());
238 let json = se_result.unwrap();
239 assert_eq!(json, JSON);
240
241 Ok(())
242 }
243
244 #[traced_test]
245 #[test]
246 fn test_de() {
247 let de_result = serde_json::from_str(JSON);
248 assert!(de_result.is_ok());
249 match de_result.unwrap() {
250 SubStatementObject::StatementRef(sr) => {
251 assert_eq!(sr.id().to_string(), ID);
252 }
253 _ => panic!("Bummer :("),
254 }
255 }
256}