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 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 return false;
80 }
81 _ => {}
82 }
83
84 true
86 }
87}