Skip to main content

cranpose_core/
task_site.rs

1/// Where an effect was written, carried onto the task it spawns.
2///
3/// A leak report that can only say "one task is still queued" names nothing.
4/// Every run prints the same number. No run says which effect it was. The
5/// site turns that count into a place to look. It is a pair of plain fields.
6/// Carrying it costs nothing until a task is spawned.
7#[derive(Clone, Copy, Debug, PartialEq, Eq)]
8pub struct TaskSite {
9    /// The path of the source file, as `file!()` gives it.
10    pub file: &'static str,
11    /// The line number in `file`, counted from 1.
12    pub line: u32,
13}
14
15impl TaskSite {
16    /// The site a macro captured with `file!()` and `line!()`.
17    pub const fn new(file: &'static str, line: u32) -> Self {
18        Self { file, line }
19    }
20}
21
22impl Default for TaskSite {
23    fn default() -> Self {
24        Self::new("unknown", 0)
25    }
26}
27
28impl std::fmt::Display for TaskSite {
29    fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30        write!(formatter, "{}:{}", self.file, self.line)
31    }
32}
33
34impl From<&'static std::panic::Location<'static>> for TaskSite {
35    fn from(location: &'static std::panic::Location<'static>) -> Self {
36        Self::new(location.file(), location.line())
37    }
38}
39
40// What a spawned UI task is called in leak reports. A site is formatted only
41// when a report asks. Spawning a task allocates no name.
42#[derive(Clone, Copy)]
43pub(crate) enum TaskLabel {
44    Unnamed,
45    Site(TaskSite),
46}
47
48impl std::fmt::Display for TaskLabel {
49    fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50        match self {
51            Self::Unnamed => formatter.write_str("unnamed"),
52            Self::Site(site) => site.fmt(formatter),
53        }
54    }
55}