Skip to main content

guinea_trace/
point.rs

1use std::fmt;
2
3/// Which bus carried a publication.
4#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
5pub enum Bus {
6    /// Every window hears it.
7    Global,
8    /// One window's own.
9    Window,
10}
11
12/// How a stored value changed.
13#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
14pub enum StoreOp {
15    Set,
16    Delete,
17    /// Everything under the path went at once.
18    DeletePrefix,
19}
20
21/// An observable point, with what identifies it.
22///
23/// Names are short type names: `processes::Kill`, not a crate path.
24#[derive(Clone, Debug, PartialEq)]
25pub enum Point {
26    /// The UI asked a feature for something.
27    Action { message: &'static str },
28    /// A message was queued for an actor.
29    Send {
30        actor: &'static str,
31        message: &'static str,
32    },
33    /// An actor handled a message.
34    Handle {
35        actor: &'static str,
36        message: &'static str,
37    },
38    /// An actor started background work whose result will come back as
39    /// `output`. `actor` is the address it will come back to, by the id the
40    /// snapshot lists it under: what a task belongs to is what that actor
41    /// belongs to.
42    Spawn {
43        actor: &'static str,
44        actor_id: u64,
45        output: &'static str,
46    },
47    /// Background work finished, and its result is on its way to the actor.
48    Settled {
49        actor: &'static str,
50        actor_id: u64,
51        output: &'static str,
52        took_us: u64,
53    },
54    /// Background work was dropped where it last awaited, because the actor
55    /// that started it is gone. Nothing comes back.
56    Cancelled {
57        actor: &'static str,
58        actor_id: u64,
59        output: &'static str,
60        took_us: u64,
61    },
62    /// An event went out.
63    Publish {
64        event: &'static str,
65        bus: Bus,
66        subscribers: usize,
67    },
68    /// An event reached a subscriber that is not an actor.
69    Deliver { event: &'static str, bus: Bus },
70    /// A reducer was changed.
71    Push { reducer: &'static str },
72    /// A router moved.
73    Navigate { root: String, to: String },
74    /// A timer fired; `timer` is its id, as the application's timers list
75    /// it.
76    Tick { timer: u64 },
77    /// A persisted value changed.
78    Store {
79        op: StoreOp,
80        path: String,
81        /// The declared field the path belongs to, `Settings.theme`, when
82        /// the store knows it.
83        field: Option<String>,
84        /// Whether the change came from outside the process, an edited file.
85        outside: bool,
86    },
87    /// A page or layout drew itself, and how long that took. Recorded only
88    /// for the frames worth looking at - see `devtools::rendering`.
89    Render {
90        segment: &'static str,
91        took_us: u64,
92    },
93    /// An ordinary `tracing` event the application wrote.
94    Log {
95        level: tracing::Level,
96        target: &'static str,
97        /// Where it was written, as the compiler named the file: relative to
98        /// the workspace root for the application's own crates.
99        file: Option<&'static str>,
100        line: Option<u32>,
101        module: Option<&'static str>,
102        /// The message, then the other fields as `name=value`.
103        text: String,
104    },
105    /// Anything else worth a line.
106    Note(String),
107}
108
109impl Point {
110    /// A short name for the kind of point, for filtering.
111    pub fn kind(&self) -> &'static str {
112        match self {
113            Point::Action { .. } => "action",
114            Point::Send { .. } => "send",
115            Point::Handle { .. } => "handle",
116            Point::Spawn { .. } => "spawn",
117            Point::Settled { .. } => "settled",
118            Point::Cancelled { .. } => "cancelled",
119            Point::Publish { .. } => "publish",
120            Point::Deliver { .. } => "deliver",
121            Point::Push { .. } => "push",
122            Point::Navigate { .. } => "navigate",
123            Point::Tick { .. } => "tick",
124            Point::Store { .. } => "store",
125            Point::Render { .. } => "render",
126            Point::Log { .. } => "log",
127            Point::Note(_) => "note",
128        }
129    }
130}
131
132impl fmt::Display for Bus {
133    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
134        f.write_str(match self {
135            Bus::Global => "global",
136            Bus::Window => "window",
137        })
138    }
139}
140
141impl fmt::Display for StoreOp {
142    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
143        f.write_str(match self {
144            StoreOp::Set => "set",
145            StoreOp::Delete => "delete",
146            StoreOp::DeletePrefix => "delete_prefix",
147        })
148    }
149}
150
151impl fmt::Display for Point {
152    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
153        match self {
154            Point::Action { message } => write!(f, "action {message}"),
155            Point::Send { actor, message } => write!(f, "send {message} → {actor}"),
156            Point::Handle { actor, message } => write!(f, "{actor} handles {message}"),
157            Point::Spawn { actor, output, .. } => write!(f, "{actor} starts work for {output}"),
158            Point::Settled {
159                actor,
160                output,
161                took_us,
162                ..
163            } => write!(
164                f,
165                "{actor} has its {output} after {:.1} ms",
166                *took_us as f64 / 1000.0
167            ),
168            Point::Cancelled {
169                actor,
170                output,
171                took_us,
172                ..
173            } => write!(
174                f,
175                "{actor} is gone: {output} cancelled after {:.1} ms",
176                *took_us as f64 / 1000.0
177            ),
178            Point::Publish {
179                event,
180                bus,
181                subscribers,
182            } => write!(f, "publish {event} on the {bus} bus to {subscribers}"),
183            Point::Deliver { event, bus } => write!(f, "deliver {event} from the {bus} bus"),
184            Point::Push { reducer } => write!(f, "push into {reducer}"),
185            Point::Navigate { root, to } => write!(f, "{root} navigates to {to}"),
186            Point::Tick { timer } => write!(f, "timer #{timer}"),
187            Point::Render { segment, took_us } => {
188                write!(f, "{segment} drew itself in {:.1} ms", *took_us as f64 / 1000.0)
189            }
190            Point::Store {
191                op,
192                path,
193                field,
194                outside,
195            } => {
196                let who = if *outside { "disk" } else { "store" };
197                let verb = match op {
198                    StoreOp::Set => "sets",
199                    StoreOp::Delete => "deletes",
200                    StoreOp::DeletePrefix => "clears",
201                };
202                write!(f, "{who} {verb} {path}")?;
203                match field {
204                    Some(field) => write!(f, " ({field})"),
205                    None => Ok(()),
206                }
207            }
208            Point::Log {
209                level,
210                target,
211                text,
212                ..
213            } => write!(f, "{level} {target}: {text}"),
214            Point::Note(text) => f.write_str(text),
215        }
216    }
217}