stix_rs/sdos/
malware_analysis.rs1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3
4use crate::common::{CommonProperties, StixObject};
5use crate::sdos::BuilderError;
6
7#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
9#[serde(rename_all = "snake_case")]
10pub struct MalwareAnalysis {
11 #[serde(flatten)]
12 pub common: CommonProperties,
13 pub product: Option<String>,
14 pub version: Option<String>,
15 pub analysis_engine_version: Option<String>,
16 pub result: Option<String>,
17}
18
19impl MalwareAnalysis {
20 pub fn builder() -> MalwareAnalysisBuilder {
21 MalwareAnalysisBuilder::default()
22 }
23}
24
25#[derive(Debug, Default)]
26pub struct MalwareAnalysisBuilder {
27 product: Option<String>,
28 version: Option<String>,
29 analysis_engine_version: Option<String>,
30 result: Option<String>,
31 created_by_ref: Option<String>,
32}
33
34impl MalwareAnalysisBuilder {
35 pub fn product(mut self, p: impl Into<String>) -> Self {
36 self.product = Some(p.into());
37 self
38 }
39
40 pub fn version(mut self, v: impl Into<String>) -> Self {
41 self.version = Some(v.into());
42 self
43 }
44
45 pub fn analysis_engine_version(mut self, v: impl Into<String>) -> Self {
46 self.analysis_engine_version = Some(v.into());
47 self
48 }
49
50 pub fn result(mut self, r: impl Into<String>) -> Self {
51 self.result = Some(r.into());
52 self
53 }
54
55 pub fn created_by_ref(mut self, r: impl Into<String>) -> Self {
56 self.created_by_ref = Some(r.into());
57 self
58 }
59
60 pub fn build(self) -> Result<MalwareAnalysis, BuilderError> {
61 let common = CommonProperties::new("malware-analysis", self.created_by_ref);
62 Ok(MalwareAnalysis {
63 common,
64 product: self.product,
65 version: self.version,
66 analysis_engine_version: self.analysis_engine_version,
67 result: self.result,
68 })
69 }
70}
71
72impl StixObject for MalwareAnalysis {
73 fn id(&self) -> &str {
74 &self.common.id
75 }
76
77 fn type_(&self) -> &str {
78 &self.common.r#type
79 }
80
81 fn created(&self) -> DateTime<Utc> {
82 self.common.created
83 }
84}
85
86impl From<MalwareAnalysis> for crate::StixObjectEnum {
87 fn from(m: MalwareAnalysis) -> Self {
88 crate::StixObjectEnum::MalwareAnalysis(m)
89 }
90}
91
92#[cfg(test)]
93mod tests {
94 use super::*;
95 use serde_json::Value;
96
97 #[test]
98 fn malware_analysis_builder() {
99 let ma = MalwareAnalysis::builder()
100 .product("AV")
101 .version("1.0")
102 .result("clean")
103 .build()
104 .unwrap();
105
106 assert_eq!(ma.product.as_deref(), Some("AV"));
107 assert_eq!(ma.common.r#type, "malware-analysis");
108 }
109
110 #[test]
111 fn malware_analysis_serialize() {
112 let ma = MalwareAnalysis::builder()
113 .product("AV")
114 .version("1.0")
115 .result("clean")
116 .build()
117 .unwrap();
118
119 let s = serde_json::to_string(&ma).unwrap();
120 let v: Value = serde_json::from_str(&s).unwrap();
121 assert_eq!(
122 v.get("type").and_then(Value::as_str).unwrap(),
123 "malware-analysis"
124 );
125 }
126}