Skip to main content

zelos_trace/
filter.rs

1use anyhow::{Result, anyhow};
2use uuid::Uuid;
3use zelos_trace_types::ipc::{IpcMessage, IpcMessageWithId};
4
5#[derive(Debug, Clone, PartialEq, Eq, Hash)]
6pub struct Filter {
7    pub segment_id: Option<Uuid>,
8    pub source_name: Option<String>,
9    pub event_name: Option<String>,
10}
11
12impl Filter {
13    pub fn new(
14        segment_id: Option<Uuid>,
15        source_name: Option<String>,
16        event_name: Option<String>,
17    ) -> Self {
18        Self {
19            segment_id,
20            source_name,
21            event_name,
22        }
23    }
24
25    pub fn any() -> Self {
26        Self {
27            segment_id: None,
28            source_name: None,
29            event_name: None,
30        }
31    }
32
33    pub fn parse(filter: &str) -> Result<Self> {
34        // Split our filter string by `/`
35        let (uuid_str, rest) = filter.split_once("/").ok_or(anyhow!("Unable to split"))?;
36        let (source_name_str, event_name_str) =
37            rest.split_once("/").ok_or(anyhow!("Unable to split"))?;
38
39        let segment_id = match uuid_str {
40            "*" => None,
41            uuid_str => Some(Uuid::parse_str(uuid_str)?),
42        };
43        let source_name = match source_name_str {
44            "*" => None,
45            source_name => Some(source_name.to_string()),
46        };
47        let event_name = match event_name_str {
48            "*" => None,
49            event_name => Some(event_name.to_string()),
50        };
51
52        Ok(Self {
53            segment_id,
54            source_name,
55            event_name,
56        })
57    }
58
59    pub fn matches(&self, msg: &IpcMessageWithId) -> bool {
60        match self.segment_id {
61            Some(segment_id) if segment_id != msg.segment_id => return false,
62            _ => {}
63        }
64
65        if let Some(match_source_name) = &self.source_name {
66            if match_source_name != &msg.source_name {
67                return false;
68            }
69        }
70
71        match (&self.event_name, &msg.msg) {
72            (Some(event_name), IpcMessage::TraceEvent(e)) => {
73                if event_name != &e.name {
74                    return false;
75                }
76            }
77            (Some(_), _) => {
78                // If message is not a TraceEvent, it can't match by event name
79                return false;
80            }
81            _ => {}
82        }
83
84        // If we've gotten this far, the message must match
85        true
86    }
87}