Skip to main content

stix_rs/observables/
email_message.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
5#[serde(rename_all = "snake_case")]
6pub struct EmailMessage {
7    pub subject: Option<String>,
8    pub body: Option<String>,
9    pub from: Option<String>,
10    pub to: Option<Vec<String>>,
11    pub date: Option<DateTime<Utc>>,
12    #[serde(flatten)]
13    pub custom_properties: std::collections::HashMap<String, serde_json::Value>,
14}
15
16impl EmailMessage {
17    pub fn builder() -> EmailMessageBuilder { EmailMessageBuilder::default() }
18}
19
20#[derive(Debug, Default)]
21pub struct EmailMessageBuilder {
22    subject: Option<String>,
23    body: Option<String>,
24    from: Option<String>,
25    to: Option<Vec<String>>,
26    date: Option<DateTime<Utc>>,
27    custom_properties: std::collections::HashMap<String, serde_json::Value>,
28}
29
30impl EmailMessageBuilder {
31    pub fn subject(mut self, s: impl Into<String>) -> Self { self.subject = Some(s.into()); self }
32    pub fn body(mut self, b: impl Into<String>) -> Self { self.body = Some(b.into()); self }
33    pub fn from(mut self, f: impl Into<String>) -> Self { self.from = Some(f.into()); self }
34    pub fn to(mut self, t: Vec<String>) -> Self { self.to = Some(t); self }
35    pub fn date(mut self, d: DateTime<Utc>) -> Self { self.date = Some(d); self }
36    pub fn property(mut self, k: impl Into<String>, v: impl Into<serde_json::Value>) -> Self { self.custom_properties.insert(k.into(), v.into()); self }
37    pub fn build(self) -> EmailMessage { EmailMessage { subject: self.subject, body: self.body, from: self.from, to: self.to, date: self.date, custom_properties: self.custom_properties } }
38}
39
40impl From<EmailMessage> for crate::StixObjectEnum { fn from(e: EmailMessage) -> Self { crate::StixObjectEnum::EmailMessage(e) } }
41
42#[cfg(test)]
43mod tests {
44    use serde_json::json;
45
46    #[test]
47    fn email_message_serde_roundtrip() {
48        let v = json!({
49            "type": "email-message",
50            "subject": "Test",
51            "from": "alice@example.com",
52            "to": ["bob@example.com"],
53            "body": "hello"
54        });
55
56        let obj: crate::StixObjectEnum = serde_json::from_value(v).expect("deserialize into StixObjectEnum");
57        match obj {
58            crate::StixObjectEnum::EmailMessage(em) => {
59                assert_eq!(em.subject.unwrap(), "Test");
60                assert_eq!(em.from.unwrap(), "alice@example.com");
61            }
62            _ => panic!("expected EmailMessage variant"),
63        }
64    }
65}