use serde::Serialize;
#[derive(Debug, Clone, Serialize)]
pub struct StructLayout {
pub name: String,
pub size: u64,
pub alignment: Option<u64>,
pub members: Vec<MemberLayout>,
pub metrics: LayoutMetrics,
#[serde(skip_serializing_if = "Option::is_none")]
pub source_location: Option<SourceLocation>,
}
#[derive(Debug, Clone, Serialize)]
pub struct MemberLayout {
pub name: String,
pub type_name: String,
pub offset: Option<u64>,
pub size: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bit_offset: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bit_size: Option<u64>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct LayoutMetrics {
pub total_size: u64,
pub useful_size: u64,
pub padding_bytes: u64,
pub padding_percentage: f64,
pub cache_lines_spanned: u32,
pub cache_line_density: f64,
pub padding_holes: Vec<PaddingHole>,
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub partial: bool,
}
#[derive(Debug, Clone, Serialize)]
pub struct PaddingHole {
pub offset: u64,
pub size: u64,
pub after_member: Option<String>,
}
#[derive(Debug, Clone, Serialize)]
pub struct SourceLocation {
pub file: String,
pub line: u64,
}
impl StructLayout {
pub fn new(name: String, size: u64, alignment: Option<u64>) -> Self {
Self {
name,
size,
alignment,
members: Vec::new(),
metrics: LayoutMetrics::default(),
source_location: None,
}
}
}
impl MemberLayout {
pub fn new(name: String, type_name: String, offset: Option<u64>, size: Option<u64>) -> Self {
Self { name, type_name, offset, size, bit_offset: None, bit_size: None }
}
pub fn end_offset(&self) -> Option<u64> {
match (self.offset, self.size) {
(Some(off), Some(sz)) => Some(off + sz),
_ => None,
}
}
}