1use clap::{Parser, Subcommand, ValueEnum};
2use std::path::PathBuf;
3
4#[derive(Parser)]
5#[command(name = "layout-audit")]
6#[command(
7 author,
8 version,
9 about = "Analyze binary memory layouts to detect padding inefficiencies"
10)]
11#[command(
12 long_about = "layout-audit parses DWARF debugging information to visualize the physical \
13layout of data structures, detect padding holes, and analyze cache line efficiency.\n\n\
14Example:\n layout-audit inspect ./target/debug/myapp --filter MyStruct"
15)]
16pub struct Cli {
17 #[command(subcommand)]
18 pub command: Commands,
19}
20
21#[derive(Subcommand)]
22pub enum Commands {
23 Inspect {
25 #[arg(value_name = "BINARY")]
27 binary: PathBuf,
28
29 #[arg(short, long)]
31 filter: Option<String>,
32
33 #[arg(short, long, value_enum, default_value = "table")]
35 output: OutputFormat,
36
37 #[arg(short, long, value_enum, default_value = "name")]
39 sort_by: SortField,
40
41 #[arg(short = 'n', long)]
43 top: Option<usize>,
44
45 #[arg(long)]
47 min_padding: Option<u64>,
48
49 #[arg(long)]
51 no_color: bool,
52
53 #[arg(long, default_value = "64", value_parser = clap::value_parser!(u32).range(1..))]
55 cache_line: u32,
56
57 #[arg(long)]
59 pretty: bool,
60
61 #[arg(long)]
63 warn_false_sharing: bool,
64 },
65
66 Diff {
68 #[arg(value_name = "OLD")]
70 old: PathBuf,
71
72 #[arg(value_name = "NEW")]
74 new: PathBuf,
75
76 #[arg(short, long)]
78 filter: Option<String>,
79
80 #[arg(short, long, value_enum, default_value = "table")]
82 output: OutputFormat,
83
84 #[arg(long, default_value = "64", value_parser = clap::value_parser!(u32).range(1..))]
86 cache_line: u32,
87
88 #[arg(long)]
90 fail_on_regression: bool,
91 },
92
93 Check {
95 #[arg(value_name = "BINARY")]
97 binary: PathBuf,
98
99 #[arg(short, long, default_value = ".layout-audit.yaml")]
101 config: PathBuf,
102
103 #[arg(long, default_value = "64", value_parser = clap::value_parser!(u32).range(1..))]
105 cache_line: u32,
106 },
107
108 Suggest {
110 #[arg(value_name = "BINARY")]
112 binary: PathBuf,
113
114 #[arg(short, long)]
116 filter: Option<String>,
117
118 #[arg(short, long, value_enum, default_value = "table")]
120 output: OutputFormat,
121
122 #[arg(long)]
124 min_savings: Option<u64>,
125
126 #[arg(long, default_value = "64", value_parser = clap::value_parser!(u32).range(1..))]
128 cache_line: u32,
129
130 #[arg(long)]
132 pretty: bool,
133
134 #[arg(long, default_value = "8")]
136 max_align: u64,
137
138 #[arg(long)]
140 sort_by_savings: bool,
141
142 #[arg(long)]
144 no_color: bool,
145 },
146}
147
148#[derive(Copy, Clone, PartialEq, Eq, ValueEnum)]
149pub enum OutputFormat {
150 Table,
151 Json,
152}
153
154#[derive(Copy, Clone, PartialEq, Eq, ValueEnum)]
155pub enum SortField {
156 Name,
158 Size,
160 Padding,
162 PaddingPct,
164}