rsigma_eval/correlation/
keys.rs1use serde::Serialize;
2
3use crate::event::{Event, EventValue};
4
5use super::types::GroupByField;
6
7#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, serde::Deserialize)]
15pub struct GroupKey(pub Vec<Option<String>>);
16
17impl GroupKey {
18 pub fn extract(
24 event: &impl Event,
25 group_by: &[GroupByField],
26 rule_refs: &[&str],
27 ) -> Option<Self> {
28 let values: Option<Vec<_>> = group_by
29 .iter()
30 .map(|field| {
31 let field_name = field.resolve(rule_refs);
32 event
33 .get_field(field_name)
34 .and_then(|v| value_to_string(&v))
35 .map(Some)
36 })
37 .collect();
38 values.map(GroupKey)
39 }
40
41 pub fn from_pairs(pairs: &[(String, String)], group_by: &[GroupByField]) -> Option<Self> {
46 let values: Option<Vec<_>> = group_by
47 .iter()
48 .map(|field| {
49 let name = field.name();
50 pairs
51 .iter()
52 .find(|(k, _)| k == name)
53 .map(|(_, v)| v.clone())
54 .map(Some)
55 })
56 .collect();
57 values.map(GroupKey)
58 }
59
60 pub fn to_pairs(&self, group_by: &[GroupByField]) -> Vec<(String, String)> {
62 group_by
63 .iter()
64 .zip(self.0.iter())
65 .filter_map(|(field, value)| {
66 value
67 .as_ref()
68 .map(|v| (field.name().to_string(), v.clone()))
69 })
70 .collect()
71 }
72}
73
74fn value_to_string(v: &EventValue) -> Option<String> {
76 match v {
77 EventValue::Str(s) => Some(s.to_string()),
78 EventValue::Int(n) => Some(n.to_string()),
79 EventValue::Float(f) => Some(f.to_string()),
80 EventValue::Bool(b) => Some(b.to_string()),
81 _ => None,
82 }
83}