xapi_rs/data/
statement_result.rs1use crate::data::{DataError, Statement, StatementId, validate_irl};
4use core::fmt;
5use iri_string::types::{IriStr, IriString};
6use serde::{Deserialize, Serialize};
7use serde_with::skip_serializing_none;
8use tracing::warn;
9
10#[skip_serializing_none]
17#[derive(Debug, Default, Deserialize, Serialize)]
18pub struct StatementResult {
19 statements: Vec<Statement>,
20 more: Option<IriString>,
21}
22
23#[skip_serializing_none]
24#[derive(Debug, Serialize)]
25pub(crate) struct StatementResultId {
26 statements: Vec<StatementId>,
27 more: Option<IriString>,
28}
29
30impl From<StatementResult> for StatementResultId {
31 fn from(value: StatementResult) -> Self {
32 StatementResultId {
33 statements: value
34 .statements
35 .into_iter()
36 .map(StatementId::from)
37 .collect(),
38 more: value.more,
39 }
40 }
41}
42
43impl StatementResult {
44 pub fn from(statements: Vec<Statement>) -> Self {
46 StatementResult {
47 statements,
48 more: None,
49 }
50 }
51
52 pub fn statements(&self) -> &Vec<Statement> {
54 self.statements.as_ref()
55 }
56
57 pub fn is_empty(&self) -> bool {
59 self.statements.is_empty()
60 }
61
62 pub fn more(&self) -> Option<&IriStr> {
64 self.more.as_deref()
65 }
66
67 pub fn set_more(&mut self, val: &str) -> Result<(), DataError> {
72 let s = val.trim();
73 if s.is_empty() {
74 warn!("Input value is empty. Unset URL");
75 self.more = None;
76 } else {
77 let iri = IriStr::new(s)?;
78 validate_irl(iri)?;
79 self.more = Some(iri.to_owned());
80 }
81 Ok(())
82 }
83}
84
85impl fmt::Display for StatementResult {
86 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
87 let statements = self
88 .statements
89 .iter()
90 .map(|x| x.to_string())
91 .collect::<Vec<_>>()
92 .join(", ");
93 if let Some(z_more) = self.more.as_ref() {
94 write!(f, "StatementResult{{[ {} ], '{}'}}", statements, z_more)
95 } else {
96 write!(f, "StatementResult{{[ {statements} ]}}")
97 }
98 }
99}
100
101impl StatementResultId {
102 pub(crate) fn from(statements: Vec<StatementId>) -> Self {
103 StatementResultId {
104 statements,
105 more: None,
106 }
107 }
108
109 pub(crate) fn set_more(&mut self, val: &str) -> Result<(), DataError> {
110 let s = val.trim();
111 let iri = IriStr::new(s)?;
112 self.more = Some(iri.to_owned());
113 Ok(())
114 }
115
116 pub(crate) fn is_empty(&self) -> bool {
117 self.statements.is_empty()
118 }
119
120 pub(crate) fn statements(&self) -> &Vec<StatementId> {
121 self.statements.as_ref()
122 }
123}
124
125#[cfg(test)]
126mod tests {
127 use super::*;
128
129 #[test]
130 fn test_deserialization() {
131 const SR: &str = r#"{
132"statements":[{
133 "id":"01932d1e-a584-79d2-b83a-6b380546b21c",
134 "actor":{"mbox":"mailto:agent99@adlnet.gov"},
135 "verb":{"id":"http://adlnet.gov/expapi/verbs/attended"},
136 "object":{
137 "objectType":"SubStatement",
138 "actor":{"objectType":"Group","member":[],"mbox":"mailto:groupb@adlnet.gov"},
139 "verb":{"id":"http://adlnet.gov/expapi/verbs/attended"},
140 "object":{"id":"http://www.example.com/unicode/36c47486-83c8-4b4f-872c-67af87e9ad10"},
141 "timestamp":"2024-11-20T00:06:06.838Z"
142 },
143 "timestamp":"2024-11-20T00:06:06.801Z",
144 "stored":"2024-11-20T00:06:06.802+00:00",
145 "authority":{"mbox":"mailto:admin@my.xapi.net"}
146}],
147"more":null}"#;
148
149 let sr: StatementResult = serde_json::from_str(SR).unwrap();
150 assert_eq!(sr.statements().len(), 1);
151 }
152}