xapi_rs/data/
object_type.rs

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