use anyhow::Context;
use anyhow::Result;
use serde::Deserialize;
use serde::Serialize;
use std::io::Write;
use std::ops::Range;
use std::path::Path;
use std::path::PathBuf;
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Default)]
pub struct TraceData {
pub traces: Vec<AddressTrace>,
}
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug)]
pub struct AddressTrace {
pub address: u64,
pub messages: Vec<String>,
}
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug)]
pub struct Section {
pub mem_range: Range<u64>,
}
impl TraceData {
pub fn write(&self, writer: &mut impl Write) -> Result<()> {
let r = postcard::to_io(self, writer);
let r: Result<()> = r.map(|_| ()).map_err(|e| e.into());
r?;
Ok(())
}
pub fn to_bytes(&self) -> Result<Vec<u8>> {
Ok(postcard::to_stdvec(self)?)
}
pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
postcard::from_bytes(bytes).context("Invalid linker trace")
}
}
#[must_use]
pub fn trace_path(base_path: &Path) -> PathBuf {
let mut new_extension = base_path.extension().unwrap_or_default().to_owned();
new_extension.push(".trace");
base_path.with_extension(new_extension)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_round_trip() {
let layout = TraceData {
traces: vec![AddressTrace {
address: 100,
messages: vec!["Test".to_owned()],
}],
};
let bytes = layout.to_bytes().unwrap();
let layout2 = TraceData::from_bytes(&bytes).unwrap();
assert_eq!(layout, layout2);
}
}