Skip to main content

xapi_data/
object_type.rs

1// SPDX-License-Identifier: GPL-3.0-or-later
2
3use crate::{DataError, ValidationError, emit_error};
4use core::fmt;
5use serde::{Deserialize, Serialize};
6
7/// _Objects_ ([Activity][1], [Agent][2], [Group][3], [StatementRef][4], etc...)
8/// in xAPI vary widely in use and can share similar properties making it hard,
9/// and sometimes impossible, to know or decide which type is meant except for
10/// the presence of a variant of this enumeration in those objects' JSON
11/// representation.
12///
13/// [1]: crate::Activity
14/// [2]: crate::Agent
15/// [3]: crate::Group
16/// [4]: crate::StatementRef
17#[derive(Clone, Debug, Default, Deserialize, Eq, Hash, PartialEq, Serialize)]
18pub enum ObjectType {
19    /// Data is part of an [Activity][crate::Activity].
20    #[default]
21    #[serde(rename = "Activity")]
22    Activity,
23    /// Data is part of an [Agent][crate::Agent].
24    #[serde(rename = "Agent")]
25    Agent,
26    /// Data is part of a [Group][crate::Group].
27    #[serde(rename = "Group")]
28    Group,
29    /// Data is part of a [Sub-Statement][crate::SubStatement].
30    #[serde(rename = "SubStatement")]
31    SubStatement,
32    /// Data is part of a [Statement-Reference][crate::StatementRef].
33    #[serde(rename = "StatementRef")]
34    StatementRef,
35    /// Data is part of an [Context Agent][crate::ContextAgent].
36    #[serde(rename = "contextAgent")]
37    ContextAgent,
38    /// Data is part of an [Context Group][crate::ContextGroup].
39    #[serde(rename = "contextGroup")]
40    ContextGroup,
41    /// Data is part of a [Person][crate::Person].
42    #[serde(rename = "Person")]
43    Person,
44}
45
46impl ObjectType {
47    #[allow(dead_code)]
48    fn from(s: &str) -> Result<Self, DataError> {
49        let s = s.trim();
50        match s {
51            "Activity" => Ok(ObjectType::Activity),
52            "Agent" => Ok(ObjectType::Agent),
53            "Group" => Ok(ObjectType::Group),
54            "SubStatement" => Ok(ObjectType::SubStatement),
55            "StatementRef" => Ok(ObjectType::StatementRef),
56            "contextAgent" => Ok(ObjectType::ContextAgent),
57            "contextGroup" => Ok(ObjectType::ContextGroup),
58            "Person" => Ok(ObjectType::Person),
59            _ => emit_error!(DataError::Validation(ValidationError::ConstraintViolation(
60                format!("Unknown|invalid ObjectType: '{s}'").into()
61            ))),
62        }
63    }
64}
65
66impl fmt::Display for ObjectType {
67    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68        let res = match self {
69            ObjectType::Activity => "Activity",
70            ObjectType::Agent => "Agent",
71            ObjectType::Group => "Group",
72            ObjectType::SubStatement => "SubStatement",
73            ObjectType::StatementRef => "StatementRef",
74            ObjectType::ContextAgent => "contextAgent",
75            ObjectType::ContextGroup => "contextGroup",
76            ObjectType::Person => "Person",
77        };
78        write!(f, "{res}")
79    }
80}
81
82#[cfg(test)]
83mod tests {
84    use super::*;
85    use tracing_test::traced_test;
86
87    #[traced_test]
88    #[test]
89    fn test_serde() {
90        let ot = ObjectType::Agent;
91        let se_result = serde_json::to_string(&ot);
92        assert!(se_result.is_ok());
93        let json = se_result.unwrap();
94        assert_eq!(json, "\"Agent\"");
95
96        let de_result = serde_json::from_str::<ObjectType>(&json);
97        assert!(de_result.is_ok());
98        let ot_ = de_result.unwrap();
99        assert_eq!(ot_, ObjectType::Agent);
100    }
101
102    #[traced_test]
103    #[test]
104    fn test_valid_from() {
105        const JSON: &str = "Agent";
106
107        let from_result = ObjectType::from(JSON);
108        assert!(from_result.is_ok());
109        let ot = from_result.unwrap();
110        assert_eq!(ot, ObjectType::Agent);
111    }
112
113    #[test]
114    fn test_invalid_from() {
115        const JSON: &str = "\"Agent\"";
116
117        let from_result = ObjectType::from(JSON);
118        // should fail b/c input is quoted
119        assert!(from_result.is_err());
120    }
121}