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