Skip to main content

defmt_decoder/elf2table/
symbol.rs

1use serde::Deserialize;
2
3use crate::Tag;
4
5#[derive(Deserialize, PartialEq, Eq, Hash)]
6pub(super) struct Symbol {
7    /// Name of the Cargo package in which the symbol is being instantiated. Used for avoiding
8    /// symbol name collisions.
9    package: String,
10
11    /// Unique identifier that disambiguates otherwise equivalent invocations in the same crate.
12    disambiguator: String,
13
14    /// Symbol categorization. Known values:
15    /// * `defmt_prim` for primitive formatting strings that are placed at the start of the `.defmt`
16    ///   section.
17    /// * `defmt_fmt`, `defmt_str` for interned format strings and string literals.
18    /// * `defmt_trace`, `defmt_debug`, `defmt_info`, `defmt_warn`, `defmt_error` for logging
19    ///   messages used at the different log levels.
20    /// * Anything starting with `defmt_` is reserved for use by defmt, other prefixes are free for
21    ///   use by third-party apps (but they all should use a prefix!).
22    tag: String,
23
24    /// Symbol data for use by the host tooling. Interpretation depends on `tag`.
25    data: String,
26
27    /// Crate name obtained via CARGO_CRATE_NAME (added since a Cargo package can contain many crates).
28    crate_name: Option<String>,
29}
30
31pub(super) enum SymbolTag {
32    /// `defmt_*` tag that we can interpret.
33    Defmt(Tag),
34
35    /// Non-`defmt_*` tag for custom tooling.
36    Custom(()),
37}
38
39impl Symbol {
40    pub fn demangle(raw: &str) -> anyhow::Result<Self> {
41        serde_json::from_str(raw)
42            .map_err(|j| anyhow::anyhow!("failed to demangle defmt symbol `{}`: {}", raw, j))
43    }
44
45    pub fn tag(&self) -> SymbolTag {
46        match &*self.tag {
47            "defmt_prim" => SymbolTag::Defmt(Tag::Prim),
48            "defmt_derived" => SymbolTag::Defmt(Tag::Derived),
49            "defmt_bitflags" => SymbolTag::Defmt(Tag::Bitflags),
50            "defmt_write" => SymbolTag::Defmt(Tag::Write),
51            "defmt_timestamp" => SymbolTag::Defmt(Tag::Timestamp),
52            "defmt_bitflags_value" => SymbolTag::Defmt(Tag::BitflagsValue),
53            "defmt_str" => SymbolTag::Defmt(Tag::Str),
54            "defmt_println" => SymbolTag::Defmt(Tag::Println),
55            "defmt_trace" => SymbolTag::Defmt(Tag::Trace),
56            "defmt_debug" => SymbolTag::Defmt(Tag::Debug),
57            "defmt_info" => SymbolTag::Defmt(Tag::Info),
58            "defmt_warn" => SymbolTag::Defmt(Tag::Warn),
59            "defmt_error" => SymbolTag::Defmt(Tag::Error),
60            _ => SymbolTag::Custom(()),
61        }
62    }
63
64    pub fn data(&self) -> &str {
65        &self.data
66    }
67
68    pub fn package(&self) -> &str {
69        &self.package
70    }
71
72    pub fn disambiguator(&self) -> &str {
73        &self.disambiguator
74    }
75
76    pub fn crate_name(&self) -> Option<&str> {
77        self.crate_name.as_deref()
78    }
79}