struct_audit/
types.rs

1use serde::Serialize;
2
3#[derive(Debug, Clone, Serialize)]
4pub struct StructLayout {
5    pub name: String,
6    pub size: u64,
7    pub alignment: Option<u64>,
8    pub members: Vec<MemberLayout>,
9    pub metrics: LayoutMetrics,
10    #[serde(skip_serializing_if = "Option::is_none")]
11    pub source_location: Option<SourceLocation>,
12}
13
14#[derive(Debug, Clone, Serialize)]
15pub struct MemberLayout {
16    pub name: String,
17    pub type_name: String,
18    pub offset: Option<u64>,
19    pub size: Option<u64>,
20    #[serde(skip_serializing_if = "Option::is_none")]
21    pub bit_offset: Option<u64>,
22    #[serde(skip_serializing_if = "Option::is_none")]
23    pub bit_size: Option<u64>,
24}
25
26#[derive(Debug, Clone, Serialize)]
27pub struct LayoutMetrics {
28    pub total_size: u64,
29    pub useful_size: u64,
30    pub padding_bytes: u64,
31    pub padding_percentage: f64,
32    pub cache_lines_spanned: u32,
33    pub cache_line_density: f64,
34    pub padding_holes: Vec<PaddingHole>,
35}
36
37#[derive(Debug, Clone, Serialize)]
38pub struct PaddingHole {
39    pub offset: u64,
40    pub size: u64,
41    pub after_member: Option<String>,
42}
43
44#[derive(Debug, Clone, Serialize)]
45pub struct SourceLocation {
46    pub file: String,
47    pub line: u64,
48}
49
50impl StructLayout {
51    pub fn new(name: String, size: u64, alignment: Option<u64>) -> Self {
52        Self {
53            name,
54            size,
55            alignment,
56            members: Vec::new(),
57            metrics: LayoutMetrics::default(),
58            source_location: None,
59        }
60    }
61}
62
63impl Default for LayoutMetrics {
64    fn default() -> Self {
65        Self {
66            total_size: 0,
67            useful_size: 0,
68            padding_bytes: 0,
69            padding_percentage: 0.0,
70            cache_lines_spanned: 0,
71            cache_line_density: 0.0,
72            padding_holes: Vec::new(),
73        }
74    }
75}
76
77impl MemberLayout {
78    pub fn new(name: String, type_name: String, offset: Option<u64>, size: Option<u64>) -> Self {
79        Self { name, type_name, offset, size, bit_offset: None, bit_size: None }
80    }
81
82    pub fn end_offset(&self) -> Option<u64> {
83        match (self.offset, self.size) {
84            (Some(off), Some(sz)) => Some(off + sz),
85            _ => None,
86        }
87    }
88}