1#![warn(missing_docs)]
4
5mod about;
6mod account;
7mod activity;
8mod activity_definition;
9mod actor;
10mod agent;
11mod attachment;
12mod canonical;
13mod ci_string;
14mod context;
15mod context_activities;
16mod context_agent;
17mod context_group;
18mod data_error;
19mod duration;
20mod email_address;
21mod extensions;
22mod fingerprint;
23mod format;
24mod group;
25mod interaction_component;
26mod interaction_type;
27mod language_map;
28mod language_tag;
29mod multi_lingual;
30mod object_type;
31mod person;
32mod result;
33mod score;
34mod statement;
35mod statement_ids;
36mod statement_object;
37mod statement_ref;
38mod statement_result;
39pub(crate) mod statement_type;
40mod sub_statement;
41mod sub_statement_object;
42mod timestamp;
43mod validate;
44mod verb;
45mod version;
46
47use crate::emit_error;
48pub use about::*;
49pub use account::*;
50pub use activity::*;
51pub use activity_definition::*;
52pub use actor::*;
53pub use agent::*;
54pub use attachment::*;
55pub use canonical::*;
56use chrono::{DateTime, SecondsFormat, Utc};
57pub use ci_string::*;
58pub use context::*;
59pub use context_activities::*;
60pub use context_agent::*;
61pub use context_group::*;
62pub use data_error::DataError;
63pub use duration::*;
64pub use email_address::*;
65pub use extensions::{EMPTY_EXTENSIONS, Extensions};
66pub use fingerprint::*;
67pub use format::*;
68pub use group::*;
69pub use interaction_component::*;
70pub use interaction_type::*;
71pub use language_map::*;
72pub use language_tag::*;
73pub use multi_lingual::*;
74pub use object_type::*;
75pub use person::*;
76pub use result::*;
77pub use score::*;
78use serde::Serializer;
79use serde_json::Value;
80pub use statement::*;
81pub use statement_ids::*;
82pub use statement_object::*;
83pub use statement_ref::*;
84pub use statement_result::*;
85pub use sub_statement::*;
86pub use sub_statement_object::*;
87pub use timestamp::MyTimestamp;
88pub use validate::*;
89pub use verb::*;
90pub use version::*;
91
92#[macro_export]
115macro_rules! add_language {
116 ( $map: expr, $tag: expr, $label: expr ) => {
117 if !$label.trim().is_empty() {
118 let label = $label.trim();
119 if $map.is_none() {
120 $map = Some(LanguageMap::new());
121 }
122 let _ = $map.as_mut().unwrap().insert($tag, label);
123 }
124 };
125}
126
127#[macro_export]
136macro_rules! set_email {
137 ( $builder: expr, $val: expr ) => {
138 if $val.trim().is_empty() {
139 $crate::emit_error!(DataError::Validation(ValidationError::Empty("mbox".into())))
140 } else {
141 $builder._mbox = Some(if let Some(x) = $val.trim().strip_prefix("mailto:") {
142 MyEmailAddress::from_str(x)?
143 } else {
144 MyEmailAddress::from_str($val.trim())?
145 });
146 $builder._sha1sum = None;
147 $builder._openid = None;
148 $builder._account = None;
149 Ok($builder)
150 }
151 };
152}
153
154#[macro_export]
159macro_rules! merge_maps {
160 ( $dst: expr, $src: expr ) => {
161 if $dst.is_none() {
162 if $src.is_some() {
163 let x = std::mem::take(&mut $src.unwrap());
164 let mut y = Some(x);
165 std::mem::swap($dst, &mut y);
166 }
167 } else if $src.is_some() {
168 let mut x = std::mem::take($dst.as_mut().unwrap());
169 let mut y = std::mem::take(&mut $src.unwrap());
170 x.append(&mut y);
171 let mut y = Some(x);
172 std::mem::swap($dst, &mut y);
173 }
174 };
175}
176
177fn check_for_nulls(val: &Value) -> Result<(), ValidationError> {
179 if let Some(obj) = val.as_object() {
180 for (k, v) in obj.iter() {
184 if v.is_null() {
185 emit_error!(ValidationError::ConstraintViolation(
186 format!("Key '{k}' is 'null'").into()
187 ))
188 } else if k != "extensions" {
189 check_for_nulls(v)?
190 }
191 }
192 }
193 Ok(())
194}
195
196fn stored_ser<S>(this: &Option<DateTime<Utc>>, ser: S) -> Result<S::Ok, S::Error>
199where
200 S: Serializer,
201{
202 if this.is_some() {
203 let s = this
204 .as_ref()
205 .unwrap()
206 .to_rfc3339_opts(SecondsFormat::Millis, true);
207 ser.serialize_str(&s)
208 } else {
209 ser.serialize_none()
210 }
211}
212
213#[cfg(test)]
214mod tests {
215 use super::*;
216 use crate::MyError;
217 use std::str::FromStr;
218
219 #[test]
220 fn test_add_language() -> Result<(), MyError> {
221 let en = MyLanguageTag::from_str("en")?;
222 let mut lm = Some(LanguageMap::new());
223
224 add_language!(lm, &en, "it vorkz");
225 let binding = lm.unwrap();
226
227 let label = binding.get(&en);
228 assert!(label.is_some());
229 assert_eq!(label.unwrap(), "it vorkz");
230
231 Ok(())
232 }
233}