Skip to main content

xapi_data/
statement_type.rs

1// SPDX-License-Identifier: GPL-3.0-or-later
2
3use crate::{
4    Attachment, DataError, Statement, StatementId, StatementResult, StatementResultId,
5    ValidationError,
6};
7use chrono::{DateTime, Utc};
8use serde::Serialize;
9use tracing::error;
10
11/// Enumeration to allow distinguishing between different kinds of a statement
12/// collection result returned by xAPI servers.
13#[derive(Debug, Serialize)]
14#[serde(untagged)]
15#[allow(dead_code)]
16pub enum StatementType {
17    /// The elements are of (full) _Statement_.
18    S(Box<Statement>),
19    /// The elements are Statement identifiers only.
20    SId(Box<StatementId>),
21    /// The elements are StatementResults.
22    SR(StatementResult),
23    /// The elements are StatementResult identifiers only.
24    SRId(StatementResultId),
25}
26
27impl StatementType {
28    /// Set the `more` property of this instance.
29    #[allow(dead_code)]
30    pub fn set_more(&mut self, val: &str) -> Result<(), DataError> {
31        match self {
32            StatementType::SR(x) => x.set_more(val),
33            StatementType::SRId(x) => x.set_more(val),
34            _ => {
35                let msg = "Not a Statement variant";
36                error!("{}", msg);
37                Err(DataError::Validation(ValidationError::ConstraintViolation(
38                    msg.into(),
39                )))
40            }
41        }
42    }
43
44    /// Return TRUE if this inner instance is a collection and is empty. Return
45    /// FALSE otherwise.
46    #[allow(dead_code)]
47    pub fn is_empty(&self) -> bool {
48        match self {
49            StatementType::SR(x) => x.is_empty(),
50            StatementType::SRId(x) => x.is_empty(),
51            _ => false,
52        }
53    }
54
55    /// If this inner instance is a single type, then return its `stored` timestamp
56    /// if set or the Unix Epoch (1970-01-01 00:00:00 UTC) if it isn't.
57    ///
58    /// Alternatively, if this inner instance is a collection, then return the
59    /// most recent `stored` timestamp of the collection's items. If `stored`
60    /// was not set for all the items of the collection, then return the Unix
61    /// Epoch.
62    #[allow(dead_code)]
63    pub fn stored(&self) -> DateTime<Utc> {
64        match self {
65            StatementType::S(x) => x.stored().map_or(DateTime::UNIX_EPOCH, |x| *x),
66            StatementType::SId(x) => x.stored().map_or(DateTime::UNIX_EPOCH, |x| *x),
67            StatementType::SR(x) => {
68                let mut stored = DateTime::UNIX_EPOCH;
69                for s in x.statements() {
70                    let ts = s.stored().map_or(&DateTime::UNIX_EPOCH, |x| x);
71                    if ts > &stored {
72                        stored = *ts
73                    };
74                }
75                stored
76            }
77            StatementType::SRId(x) => {
78                let mut stored = DateTime::UNIX_EPOCH;
79                for s in x.statements() {
80                    let ts = s.stored().map_or(&DateTime::UNIX_EPOCH, |x| x);
81                    if ts > &stored {
82                        stored = *ts
83                    };
84                }
85                stored
86            }
87        }
88    }
89
90    /// Return the potentially empty collection of [Attachment]s.
91    #[allow(dead_code)]
92    pub fn attachments(&self) -> Vec<Attachment> {
93        match self {
94            StatementType::S(x) => x.attachments().to_vec(),
95            StatementType::SId(x) => x.attachments().to_vec(),
96            StatementType::SR(x) => {
97                let mut v = vec![];
98                for s in x.statements() {
99                    v.extend_from_slice(s.attachments());
100                }
101                v
102            }
103            StatementType::SRId(x) => {
104                let mut v = vec![];
105                for s in x.statements() {
106                    v.extend_from_slice(s.attachments());
107                }
108                v
109            }
110        }
111    }
112}