1#[derive(Debug, Clone)]
5pub struct Pattern {
6 inner: stix::pattern::Pattern,
7}
8
9impl Pattern {
10 pub(crate) fn new(inner: stix::pattern::Pattern) -> Self {
11 Pattern { inner }
12 }
13
14 pub(crate) fn inner(&self) -> &stix::pattern::Pattern {
15 &self.inner
16 }
17
18 pub fn to_json(&self) -> String {
20 serde_json::to_string(&self.inner).unwrap_or_else(|_| "null".to_string())
22 }
23}
24
25#[derive(Debug, Clone)]
27pub struct Bundle {
28 inner: stix::model::Bundle,
29}
30
31impl Bundle {
32 pub(crate) fn new(inner: stix::model::Bundle) -> Self {
33 Bundle { inner }
34 }
35
36 pub(crate) fn inner(&self) -> &stix::model::Bundle {
37 &self.inner
38 }
39
40 pub fn object_count(&self) -> usize {
42 self.inner.objects.len()
43 }
44
45 pub fn object_json(&self, index: usize) -> Option<String> {
47 let obj = self.inner.objects.get(index)?;
48 Some(serde_json::to_string(obj).unwrap_or_else(|_| "null".to_string()))
49 }
50}
51
52#[derive(Debug, Clone, PartialEq, Eq)]
54pub struct MatchOutcome {
55 pub matched: bool,
57 pub observations: Vec<u64>,
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64
65 #[test]
66 fn pattern_to_json_round_trips() {
67 let inner = stix::parse("[ipv4-addr:value = '1.2.3.4']").unwrap();
68 let handle = Pattern::new(inner.clone());
69 let json = handle.to_json();
70 let back: stix::pattern::Pattern = serde_json::from_str(&json).unwrap();
71 assert_eq!(back, inner);
72 }
73
74 #[test]
75 fn bundle_object_access() {
76 let raw = r#"{"type":"bundle","id":"bundle--1","objects":[
77 {"type":"ipv4-addr","id":"ipv4-addr--1","value":"1.2.3.4"}
78 ]}"#;
79 let inner = stix::model::Bundle::from_json_str(raw).unwrap();
80 let handle = Bundle::new(inner);
81 assert_eq!(handle.object_count(), 1);
82 let obj_json = handle.object_json(0).unwrap();
83 assert!(obj_json.contains("ipv4-addr--1"));
84 assert!(handle.object_json(5).is_none());
85 }
86
87 #[test]
88 fn match_outcome_fields() {
89 let o = MatchOutcome {
90 matched: true,
91 observations: vec![0, 2],
92 };
93 assert!(o.matched);
94 assert_eq!(o.observations, vec![0, 2]);
95 }
96}