1use crate::{
4 data::{
5 Activity, ActivityId, Agent, AgentId, DataError, Fingerprint, Group, GroupId, StatementRef,
6 SubStatement, SubStatementId, Validate, ValidationError,
7 },
8 emit_error,
9};
10use core::fmt;
11use serde::{
12 Deserialize, Serialize,
13 de::{self},
14};
15use serde_json::Value;
16use std::hash::Hasher;
17use tracing::{debug, error};
18
19#[derive(Debug, PartialEq, Serialize)]
39#[serde(untagged)]
40pub enum StatementObject {
41 Agent(Agent),
43 Group(Group),
45 StatementRef(StatementRef),
47 SubStatement(Box<SubStatement>),
49 Activity(Activity),
51}
52
53#[derive(Debug, Serialize)]
54#[serde(untagged)]
55pub(crate) enum StatementObjectId {
56 Activity(ActivityId),
57 Agent(AgentId),
58 Group(GroupId),
59 StatementRef(StatementRef),
60 SubStatement(Box<SubStatementId>),
61}
62
63impl From<StatementObject> for StatementObjectId {
64 fn from(value: StatementObject) -> Self {
65 match value {
66 StatementObject::Agent(agent) => StatementObjectId::Agent(agent.into()),
67 StatementObject::Group(group) => StatementObjectId::Group(group.into()),
68 StatementObject::StatementRef(stmt_ref) => StatementObjectId::StatementRef(stmt_ref),
69 StatementObject::SubStatement(sub_stmt) => {
70 StatementObjectId::SubStatement(Box::new(sub_stmt.into()))
71 }
72 StatementObject::Activity(activity) => StatementObjectId::Activity(activity.into()),
73 }
74 }
75}
76
77impl From<StatementObjectId> for StatementObject {
78 fn from(value: StatementObjectId) -> Self {
79 match value {
80 StatementObjectId::Activity(x) => StatementObject::Activity(Activity::from(x)),
81 StatementObjectId::Agent(x) => StatementObject::Agent(Agent::from(x)),
82 StatementObjectId::Group(x) => StatementObject::Group(Group::from(x)),
83 StatementObjectId::StatementRef(x) => StatementObject::StatementRef(x),
84 StatementObjectId::SubStatement(x) => {
85 StatementObject::SubStatement(Box::new(SubStatement::from(*x)))
86 }
87 }
88 }
89}
90
91impl<'de> Deserialize<'de> for StatementObject {
92 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
93 where
94 D: serde::Deserializer<'de>,
95 {
96 let v: Value = Deserialize::deserialize(deserializer)?;
97 match v {
98 Value::Object(ref map) => {
99 let ot = map.get("objectType").map_or(
100 {
101 debug!("Missing 'objectType'. Assume 'Activity' + continue");
102 Some("Activity")
103 },
104 |x| x.as_str(),
105 );
106 match ot {
107 Some("Agent") => match Agent::deserialize(v) {
108 Ok(x) => Ok(StatementObject::Agent(x)),
109 Err(x) => {
110 let msg = format!("input is not Agent: {x}");
111 error!("objectType is 'Agent', but {}", msg);
112 Err(de::Error::custom(msg))
113 }
114 },
115 Some("Group") => match Group::deserialize(v) {
116 Ok(x) => Ok(StatementObject::Group(x)),
117 Err(x) => {
118 let msg = format!("input is not Group: {x}");
119 error!("objectType is 'Group', but {}", msg);
120 Err(de::Error::custom(msg))
121 }
122 },
123 Some("StatementRef") => match StatementRef::deserialize(v) {
124 Ok(x) => Ok(StatementObject::StatementRef(x)),
125 Err(x) => {
126 let msg = format!("input is not StatementRef: {x}");
127 error!("objectType is 'StatementRef', but {}", msg);
128 Err(de::Error::custom(msg))
129 }
130 },
131 Some("SubStatement") => match SubStatement::deserialize(v) {
132 Ok(x) => Ok(StatementObject::SubStatement(Box::new(x))),
133 Err(x) => {
134 let msg = format!("input is not SubStatement: {x}");
135 error!("objectType is 'SubStatement', but {}", msg);
136 Err(de::Error::custom(msg))
137 }
138 },
139 Some("Activity") => match Activity::deserialize(v) {
140 Ok(x) => Ok(StatementObject::Activity(x)),
141 Err(x) => {
142 let msg = format!("input is not Activity: {x}");
143 error!("objectType is 'Activity', but {}", msg);
144 Err(de::Error::custom(msg))
145 }
146 },
147 _ => Err(de::Error::custom(
148 "Unknown 'objectType'. Expected Agent | Group | StatementRef | SubStatement | Activity",
149 )),
150 }
151 }
152 _ => Err(de::Error::custom("Expected JSON object")),
153 }
154 }
155}
156
157#[derive(Debug)]
160#[doc(hidden)]
161pub enum ObjectKind {
162 ActivityObject = 0,
164 AgentObject = 1,
166 GroupObject = 2,
168 StatementRefObject = 3,
170 SubStatementObject = 4,
172}
173
174impl fmt::Display for ObjectKind {
175 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
176 match self {
177 ObjectKind::ActivityObject => write!(f, "[Activity]"),
178 ObjectKind::AgentObject => write!(f, "[Agent]"),
179 ObjectKind::GroupObject => write!(f, "[Group]"),
180 ObjectKind::StatementRefObject => write!(f, "[StatementRef]"),
181 ObjectKind::SubStatementObject => write!(f, "[SubStatement]"),
182 }
183 }
184}
185
186impl From<i16> for ObjectKind {
187 fn from(value: i16) -> Self {
188 match value {
189 0 => ObjectKind::ActivityObject,
190 1 => ObjectKind::AgentObject,
191 2 => ObjectKind::GroupObject,
192 3 => ObjectKind::StatementRefObject,
193 _ => ObjectKind::SubStatementObject,
194 }
195 }
196}
197
198impl StatementObject {
199 pub fn from_activity(obj: Activity) -> Self {
201 StatementObject::Activity(obj)
202 }
203
204 pub fn from_agent(obj: Agent) -> Self {
206 StatementObject::Agent(obj)
207 }
208
209 pub fn from_group(obj: Group) -> Self {
211 StatementObject::Group(obj)
212 }
213
214 pub fn from_statement_ref(obj: StatementRef) -> Self {
216 StatementObject::StatementRef(obj)
217 }
218
219 pub fn from_sub_statement(obj: SubStatement) -> Self {
221 StatementObject::SubStatement(Box::new(obj))
222 }
223
224 pub fn is_activity(&self) -> bool {
228 matches!(self, StatementObject::Activity(_))
229 }
230
231 pub fn is_agent(&self) -> bool {
235 matches!(self, StatementObject::Agent(_))
236 }
237
238 pub fn is_group(&self) -> bool {
242 matches!(self, StatementObject::Group(_))
243 }
244
245 pub fn is_statement_ref(&self) -> bool {
249 matches!(self, StatementObject::StatementRef(_))
250 }
251
252 pub fn is_sub_statement(&self) -> bool {
256 matches!(self, StatementObject::SubStatement(_))
257 }
258
259 pub fn as_activity(&self) -> Result<Activity, DataError> {
261 match self {
262 StatementObject::Activity(x) => Ok(x.to_owned()),
263 _ => emit_error!(DataError::Validation(ValidationError::ConstraintViolation(
264 format!("This ({self}) is NOT an Activity").into()
265 ))),
266 }
267 }
268
269 pub fn as_agent(&self) -> Result<Agent, DataError> {
271 match self {
272 StatementObject::Agent(x) => Ok(x.to_owned()),
273 _ => emit_error!(DataError::Validation(ValidationError::ConstraintViolation(
274 format!("This ({self}) is NOT an Agent").into()
275 ))),
276 }
277 }
278
279 pub fn as_group(&self) -> Result<Group, DataError> {
281 match self {
282 StatementObject::Group(x) => Ok(x.to_owned()),
283 _ => emit_error!(DataError::Validation(ValidationError::ConstraintViolation(
284 format!("This ({self}) is NOT a Group").into()
285 ))),
286 }
287 }
288
289 pub fn as_statement_ref(&self) -> Result<StatementRef, DataError> {
292 match self {
293 StatementObject::StatementRef(x) => Ok(x.to_owned()),
294 _ => emit_error!(DataError::Validation(ValidationError::ConstraintViolation(
295 format!("This ({self}) is NOT a Statement-Ref").into()
296 ))),
297 }
298 }
299
300 pub fn as_sub_statement(&self) -> Result<SubStatement, DataError> {
303 match self {
304 StatementObject::SubStatement(x) => Ok(*x.to_owned()),
305 _ => emit_error!(DataError::Validation(ValidationError::ConstraintViolation(
306 format!("This ({self}) is NOT a Sub-Statement").into()
307 ))),
308 }
309 }
310
311 pub fn kind(&self) -> ObjectKind {
313 match self {
314 StatementObject::Activity(_) => ObjectKind::ActivityObject,
315 StatementObject::Agent(_) => ObjectKind::AgentObject,
316 StatementObject::Group(_) => ObjectKind::GroupObject,
317 StatementObject::StatementRef(_) => ObjectKind::StatementRefObject,
318 StatementObject::SubStatement(_) => ObjectKind::SubStatementObject,
319 }
320 }
321}
322
323impl fmt::Display for StatementObject {
324 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
325 match self {
326 StatementObject::Agent(x) => write!(f, "{x}"),
327 StatementObject::Group(x) => write!(f, "{x}"),
328 StatementObject::StatementRef(x) => write!(f, "{x}"),
329 StatementObject::SubStatement(x) => write!(f, "{x}"),
330 StatementObject::Activity(x) => write!(f, "{x}"),
331 }
332 }
333}
334
335impl Fingerprint for StatementObject {
336 fn fingerprint<H: Hasher>(&self, state: &mut H) {
337 match self {
338 StatementObject::Agent(x) => x.fingerprint(state),
339 StatementObject::Group(x) => x.fingerprint(state),
340 StatementObject::StatementRef(x) => x.fingerprint(state),
341 StatementObject::SubStatement(x) => x.fingerprint(state),
342 StatementObject::Activity(x) => x.fingerprint(state),
343 }
344 }
345}
346
347impl Validate for StatementObject {
348 fn validate(&self) -> Vec<ValidationError> {
349 match self {
350 StatementObject::Agent(x) => x.validate(),
351 StatementObject::Group(x) => x.validate(),
352 StatementObject::StatementRef(x) => x.validate(),
353 StatementObject::SubStatement(x) => x.validate(),
354 StatementObject::Activity(x) => x.validate(),
355 }
356 }
357}