wasm4pm_compat/
eventlog.rs1use std::fmt;
7
8#[derive(Debug, Clone, PartialEq, Eq)]
10pub struct Event {
11 activity: String,
12 timestamp_ns: u64,
13 resource: Option<String>,
14 lifecycle: Option<String>,
15}
16
17impl Event {
18 pub fn new(activity: &str) -> Self {
19 Event {
20 activity: activity.to_owned(),
21 timestamp_ns: 0,
22 resource: None,
23 lifecycle: None,
24 }
25 }
26
27 #[must_use]
28 pub fn at_ns(mut self, ns: u64) -> Self {
29 self.timestamp_ns = ns;
30 self
31 }
32
33 #[must_use]
34 pub fn by(mut self, resource: &str) -> Self {
35 self.resource = Some(resource.to_owned());
36 self
37 }
38
39 #[must_use]
40 pub fn with_lifecycle(mut self, lc: &str) -> Self {
41 self.lifecycle = Some(lc.to_owned());
42 self
43 }
44
45 pub fn activity(&self) -> &str {
46 &self.activity
47 }
48 pub fn timestamp_ns(&self) -> Option<u64> {
49 if self.timestamp_ns == 0 {
50 None
51 } else {
52 Some(self.timestamp_ns)
53 }
54 }
55 pub fn resource(&self) -> Option<&str> {
56 self.resource.as_deref()
57 }
58 pub fn lifecycle(&self) -> Option<&str> {
59 self.lifecycle.as_deref()
60 }
61}
62
63#[derive(Debug, Clone, PartialEq, Eq)]
65pub struct Trace {
66 case_id: String,
67 events: Vec<Event>,
68}
69
70impl Trace {
71 pub fn new(case_id: &str, events: impl IntoIterator<Item = Event>) -> Self {
72 Trace {
73 case_id: case_id.to_owned(),
74 events: events.into_iter().collect(),
75 }
76 }
77
78 pub fn from_events(events: impl IntoIterator<Item = Event>) -> Self {
79 Trace {
80 case_id: "_".to_owned(),
81 events: events.into_iter().collect(),
82 }
83 }
84
85 pub fn case_id(&self) -> &str {
86 &self.case_id
87 }
88 pub fn len(&self) -> usize {
89 self.events.len()
90 }
91 pub fn is_empty(&self) -> bool {
92 self.events.is_empty()
93 }
94 pub fn events(&self) -> &[Event] {
95 &self.events
96 }
97
98 pub fn validate(&self) -> Result<(), EventLogRefusal> {
99 if self.events.is_empty() {
100 return Err(EventLogRefusal::EmptyTrace);
101 }
102 let stamped: Vec<u64> = self
103 .events
104 .iter()
105 .map(|e| e.timestamp_ns)
106 .filter(|&t| t > 0)
107 .collect();
108 for w in stamped.windows(2) {
109 if w[1] < w[0] {
110 return Err(EventLogRefusal::NonMonotonicTrace);
111 }
112 }
113 Ok(())
114 }
115}
116
117#[derive(Debug, Clone, PartialEq, Eq, Default)]
119pub struct EventLog {
120 traces: Vec<Trace>,
121}
122
123impl EventLog {
124 pub fn from_traces(traces: impl IntoIterator<Item = Trace>) -> Self {
125 EventLog {
126 traces: traces.into_iter().collect(),
127 }
128 }
129
130 pub fn traces(&self) -> &[Trace] {
131 &self.traces
132 }
133
134 pub fn trace_count(&self) -> usize {
135 self.traces.len()
136 }
137
138 pub fn event_count(&self) -> usize {
139 self.traces.iter().map(|t| t.len()).sum()
140 }
141
142 pub fn validate(&self) -> Result<(), EventLogRefusal> {
143 for trace in &self.traces {
144 trace.validate()?;
145 }
146 Ok(())
147 }
148}
149
150#[derive(Debug, Clone, Default)]
152pub struct EventStream {
153 events: Vec<Event>,
154}
155
156impl EventStream {
157 pub fn new() -> Self {
158 EventStream::default()
159 }
160 pub fn push(&mut self, e: Event) {
161 self.events.push(e);
162 }
163 pub fn is_empty(&self) -> bool {
164 self.events.is_empty()
165 }
166 pub fn len(&self) -> usize {
167 self.events.len()
168 }
169}
170
171#[derive(Debug, Clone, PartialEq, Eq)]
176pub enum EventLogRefusal {
177 EmptyTrace,
179 NonMonotonicTrace,
181 MissingCaseId,
182 MissingActivity,
183 MissingTimestamp,
184 DuplicateEvent,
185 InvalidLifecycle,
186}
187
188impl fmt::Display for EventLogRefusal {
189 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
190 match self {
191 EventLogRefusal::EmptyTrace => write!(f, "EmptyTrace"),
192 EventLogRefusal::NonMonotonicTrace => write!(f, "NonMonotonicTrace"),
193 EventLogRefusal::MissingCaseId => write!(f, "MissingCaseId"),
194 EventLogRefusal::MissingActivity => write!(f, "MissingActivity"),
195 EventLogRefusal::MissingTimestamp => write!(f, "MissingTimestamp"),
196 EventLogRefusal::DuplicateEvent => write!(f, "DuplicateEvent"),
197 EventLogRefusal::InvalidLifecycle => write!(f, "InvalidLifecycle"),
198 }
199 }
200}
201
202impl std::error::Error for EventLogRefusal {}