1use std::fmt;
2
3#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
5pub enum Bus {
6 Global,
8 Window,
10}
11
12#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
14pub enum StoreOp {
15 Set,
16 Delete,
17 DeletePrefix,
19}
20
21#[derive(Clone, Debug, PartialEq)]
25pub enum Point {
26 Action { message: &'static str },
28 Send {
30 actor: &'static str,
31 message: &'static str,
32 },
33 Handle {
35 actor: &'static str,
36 message: &'static str,
37 },
38 Spawn {
43 actor: &'static str,
44 actor_id: u64,
45 output: &'static str,
46 },
47 Settled {
49 actor: &'static str,
50 actor_id: u64,
51 output: &'static str,
52 took_us: u64,
53 },
54 Cancelled {
57 actor: &'static str,
58 actor_id: u64,
59 output: &'static str,
60 took_us: u64,
61 },
62 Source {
66 actor: &'static str,
67 actor_id: u64,
68 output: &'static str,
69 },
70 Arrived {
73 actor: &'static str,
74 actor_id: u64,
75 output: &'static str,
76 source: u64,
77 },
78 Closed {
81 actor: &'static str,
82 actor_id: u64,
83 output: &'static str,
84 took_us: u64,
85 gone: bool,
86 },
87 Publish {
89 event: &'static str,
90 bus: Bus,
91 subscribers: usize,
92 },
93 Deliver { event: &'static str, bus: Bus },
95 Push { reducer: &'static str },
97 Navigate { root: String, to: String },
99 Tick { timer: u64 },
102 Store {
104 op: StoreOp,
105 path: String,
106 field: Option<String>,
109 outside: bool,
111 },
112 Render {
115 segment: &'static str,
116 took_us: u64,
117 },
118 Log {
120 level: tracing::Level,
121 target: &'static str,
122 file: Option<&'static str>,
125 line: Option<u32>,
126 module: Option<&'static str>,
127 text: String,
129 },
130 Span {
135 name: &'static str,
136 level: tracing::Level,
138 target: &'static str,
139 file: Option<&'static str>,
141 line: Option<u32>,
142 module: Option<&'static str>,
143 fields: String,
145 },
146 Note(String),
148}
149
150impl Point {
151 pub fn kind(&self) -> &'static str {
153 match self {
154 Point::Action { .. } => "action",
155 Point::Send { .. } => "send",
156 Point::Handle { .. } => "handle",
157 Point::Spawn { .. } => "spawn",
158 Point::Settled { .. } => "settled",
159 Point::Cancelled { .. } => "cancelled",
160 Point::Source { .. } => "source",
161 Point::Arrived { .. } => "arrived",
162 Point::Closed { .. } => "closed",
163 Point::Publish { .. } => "publish",
164 Point::Deliver { .. } => "deliver",
165 Point::Push { .. } => "push",
166 Point::Navigate { .. } => "navigate",
167 Point::Tick { .. } => "tick",
168 Point::Store { .. } => "store",
169 Point::Render { .. } => "render",
170 Point::Log { .. } => "log",
171 Point::Span { .. } => "span",
172 Point::Note(_) => "note",
173 }
174 }
175}
176
177impl fmt::Display for Bus {
178 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
179 f.write_str(match self {
180 Bus::Global => "global",
181 Bus::Window => "window",
182 })
183 }
184}
185
186impl fmt::Display for StoreOp {
187 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
188 f.write_str(match self {
189 StoreOp::Set => "set",
190 StoreOp::Delete => "delete",
191 StoreOp::DeletePrefix => "delete_prefix",
192 })
193 }
194}
195
196impl fmt::Display for Point {
197 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
198 match self {
199 Point::Action { message } => write!(f, "action {message}"),
200 Point::Send { actor, message } => write!(f, "send {message} → {actor}"),
201 Point::Handle { actor, message, .. } => write!(f, "{actor} handles {message}"),
202 Point::Spawn { actor, output, .. } => write!(f, "{actor} starts work for {output}"),
203 Point::Settled {
204 actor,
205 output,
206 took_us,
207 ..
208 } => write!(
209 f,
210 "{actor} has its {output} after {:.1} ms",
211 *took_us as f64 / 1000.0
212 ),
213 Point::Cancelled {
214 actor,
215 output,
216 took_us,
217 ..
218 } => write!(
219 f,
220 "{actor} is gone: {output} cancelled after {:.1} ms",
221 *took_us as f64 / 1000.0
222 ),
223 Point::Source { actor, output, .. } => write!(f, "{actor} opens a source of {output}"),
224 Point::Arrived { actor, output, .. } => write!(f, "{output} arrives at {actor}"),
225 Point::Closed {
226 actor,
227 output,
228 took_us,
229 gone: true,
230 ..
231 } => write!(
232 f,
233 "{actor} is gone: its source of {output} closed after {:.1} ms",
234 *took_us as f64 / 1000.0
235 ),
236 Point::Closed {
237 actor,
238 output,
239 took_us,
240 ..
241 } => write!(
242 f,
243 "{actor}'s source of {output} ran dry after {:.1} ms",
244 *took_us as f64 / 1000.0
245 ),
246 Point::Publish {
247 event,
248 bus,
249 subscribers,
250 } => write!(f, "publish {event} on the {bus} bus to {subscribers}"),
251 Point::Deliver { event, bus } => write!(f, "deliver {event} from the {bus} bus"),
252 Point::Push { reducer } => write!(f, "push into {reducer}"),
253 Point::Navigate { root, to } => write!(f, "{root} navigates to {to}"),
254 Point::Tick { timer } => write!(f, "timer #{timer}"),
255 Point::Render { segment, took_us } => {
256 write!(f, "{segment} drew itself in {:.1} ms", *took_us as f64 / 1000.0)
257 }
258 Point::Store {
259 op,
260 path,
261 field,
262 outside,
263 } => {
264 let who = if *outside { "disk" } else { "store" };
265 let verb = match op {
266 StoreOp::Set => "sets",
267 StoreOp::Delete => "deletes",
268 StoreOp::DeletePrefix => "clears",
269 };
270 write!(f, "{who} {verb} {path}")?;
271 match field {
272 Some(field) => write!(f, " ({field})"),
273 None => Ok(()),
274 }
275 }
276 Point::Log {
277 level,
278 target,
279 text,
280 ..
281 } => write!(f, "{level} {target}: {text}"),
282 Point::Span { name, fields, .. } if fields.is_empty() => f.write_str(name),
283 Point::Span { name, fields, .. } => write!(f, "{name} {fields}"),
284 Point::Note(text) => f.write_str(text),
285 }
286 }
287}