use std::fmt::Write;
use crate::cargo;
pub(crate) fn mangled(defmt_tag: &str, data: &str) -> String {
Symbol::new(defmt_tag, data).mangle()
}
struct Symbol<'a> {
package: String,
disambiguator: u64,
tag: String,
data: &'a str,
crate_name: String,
}
impl<'a> Symbol<'a> {
fn new(tag: &'a str, data: &'a str) -> Self {
Self {
package: cargo::package_name(),
disambiguator: super::crate_local_disambiguator(),
tag: format!("defmt_{tag}"),
data,
crate_name: cargo::crate_name(),
}
}
fn mangle(&self) -> String {
format!(
r#"{{"package":"{}","tag":"{}","data":"{}","disambiguator":"{}","crate_name":"{}"}}"#,
json_escape(&self.package),
json_escape(&self.tag),
json_escape(self.data),
self.disambiguator,
json_escape(&self.crate_name),
)
}
}
fn json_escape(string: &str) -> String {
let mut escaped = String::new();
for c in string.chars() {
match c {
'\\' => escaped.push_str("\\\\"),
'\"' => escaped.push_str("\\\""),
'\n' => escaped.push_str("\\n"),
c if c.is_control() || c == '@' => write!(escaped, "\\u{:04x}", c as u32).unwrap(),
c => escaped.push(c),
}
}
escaped
}