miden_debug_engine/exec/
event.rs1use std::sync::LazyLock;
3
4use miden_core::events::{EventId, EventName};
5
6pub const FRAME_START_EVENT: EventName = EventName::new("readonly::miden_debug::frame_start");
8static FRAME_START_EVENT_ID: LazyLock<EventId> = LazyLock::new(|| FRAME_START_EVENT.to_event_id());
9
10pub const FRAME_END_EVENT: EventName = EventName::new("readonly::miden_debug::frame_end");
12static FRAME_END_EVENT_ID: LazyLock<EventId> = LazyLock::new(|| FRAME_END_EVENT.to_event_id());
13
14pub const PRINTLN_EVENT: EventName = EventName::new("readonly::miden_debug::println");
22static PRINTLN_EVENT_ID: LazyLock<EventId> = LazyLock::new(|| PRINTLN_EVENT.to_event_id());
23
24#[derive(Debug, Clone)]
26#[repr(u32)]
27pub enum Event {
28 FrameStart,
29 FrameEnd,
30 PrintLn,
31 UserDefined(EventName),
32 Unknown(EventId),
33}
34
35impl std::hash::Hash for Event {
36 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
37 self.as_event_id().hash(state);
38 }
39}
40
41impl Eq for Event {}
42
43impl PartialEq for Event {
44 fn eq(&self, other: &Self) -> bool {
45 self.as_event_id() == other.as_event_id()
46 }
47}
48
49impl PartialOrd for Event {
50 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
51 Some(self.cmp(other))
52 }
53}
54
55impl Ord for Event {
56 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
57 use std::cmp::Ordering;
58 if self.as_event_id() == other.as_event_id() {
59 return Ordering::Equal;
60 }
61 match (self, other) {
62 (Self::Unknown(a), Self::Unknown(b)) => a.cmp(b),
63 (Self::Unknown(_), _) => Ordering::Greater,
64 (_, Self::Unknown(_)) => Ordering::Less,
65 (a, b) => a.as_event_name().unwrap().as_str().cmp(b.as_event_name().unwrap().as_str()),
66 }
67 }
68}
69
70impl Event {
71 #[inline(always)]
72 pub fn is_frame_start(&self) -> bool {
73 matches!(self, Self::FrameStart)
74 }
75
76 #[inline(always)]
77 pub fn is_frame_end(&self) -> bool {
78 matches!(self, Self::FrameEnd)
79 }
80
81 pub fn as_event_id(&self) -> EventId {
82 match self {
83 Self::FrameStart => *FRAME_START_EVENT_ID,
84 Self::FrameEnd => *FRAME_END_EVENT_ID,
85 Self::PrintLn => *PRINTLN_EVENT_ID,
86 Self::UserDefined(event) => event.to_event_id(),
87 Self::Unknown(event) => *event,
88 }
89 }
90
91 pub fn as_event_name(&self) -> Option<EventName> {
95 Some(match self {
96 Self::FrameStart => FRAME_START_EVENT,
97 Self::FrameEnd => FRAME_END_EVENT,
98 Self::PrintLn => PRINTLN_EVENT,
99 Self::UserDefined(name) => name.clone(),
100 Self::Unknown(_) => return None,
101 })
102 }
103}
104
105impl core::fmt::Display for Event {
106 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
107 match self {
108 Self::FrameStart => f.write_str(FRAME_START_EVENT.as_str()),
109 Self::FrameEnd => f.write_str(FRAME_END_EVENT.as_str()),
110 Self::PrintLn => f.write_str(PRINTLN_EVENT.as_str()),
111 Self::UserDefined(name) => f.write_str(name.as_str()),
112 Self::Unknown(id) => write!(f, "{id}"),
113 }
114 }
115}
116
117impl From<EventId> for Event {
118 fn from(raw: EventId) -> Self {
119 if raw == *FRAME_START_EVENT_ID {
120 Self::FrameStart
121 } else if raw == *FRAME_END_EVENT_ID {
122 Self::FrameEnd
123 } else if raw == *PRINTLN_EVENT_ID {
124 Self::PrintLn
125 } else {
126 Self::Unknown(raw)
127 }
128 }
129}
130
131impl From<Event> for EventId {
132 fn from(event: Event) -> Self {
133 event.as_event_id()
134 }
135}
136
137impl From<EventName> for Event {
138 fn from(value: EventName) -> Self {
139 if value == FRAME_START_EVENT {
140 Self::FrameStart
141 } else if value == FRAME_END_EVENT {
142 Self::FrameEnd
143 } else if value == PRINTLN_EVENT {
144 Self::PrintLn
145 } else {
146 Self::UserDefined(value)
147 }
148 }
149}
150
151#[cfg(test)]
152mod tests {
153 use super::*;
154
155 #[test]
156 fn print_ln_event_roundtrips() {
157 assert_eq!(Event::from(PRINTLN_EVENT.to_event_id()), Event::PrintLn);
158 assert_eq!(Event::PrintLn.as_event_id(), *PRINTLN_EVENT_ID);
159 assert_eq!(Event::from(PRINTLN_EVENT), Event::PrintLn);
160 }
161}