Skip to main content

abi_audit_core/
model.rs

1use std::path::PathBuf;
2
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
6#[serde(rename_all = "snake_case")]
7pub enum Severity {
8    Warning,
9    Error,
10}
11
12#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
13pub struct Finding {
14    pub code: String,
15    pub severity: Severity,
16    pub message: String,
17    pub package: String,
18    pub export: Option<String>,
19    pub location: Option<SourceLocation>,
20    pub evidence: Vec<String>,
21}
22
23#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
24pub struct SourceLocation {
25    pub path: String,
26    pub line: usize,
27}
28
29#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
30pub struct WorkspaceSnapshot {
31    pub schema_version: u32,
32    pub generated_at_utc: String,
33    pub workspace_root: String,
34    #[serde(default, alias = "configured_targets")]
35    pub targets: Vec<TargetSnapshot>,
36    pub packages: Vec<PackageSnapshot>,
37}
38
39#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Default)]
40#[serde(rename_all = "snake_case")]
41pub enum TargetOrigin {
42    #[default]
43    Configured,
44    Auto,
45}
46
47#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Default)]
48#[serde(rename_all = "snake_case")]
49pub enum HeaderSource {
50    Configured,
51    Auto,
52    #[default]
53    None,
54}
55
56#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Default)]
57#[serde(rename_all = "snake_case")]
58pub enum HeaderSyncTool {
59    #[default]
60    Cbindgen,
61}
62
63#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
64#[serde(rename_all = "snake_case")]
65pub enum ArtifactKind {
66    Cdylib,
67    Staticlib,
68}
69
70#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
71pub struct TargetSnapshot {
72    pub package: String,
73    pub headers: Vec<String>,
74    #[serde(default)]
75    pub origin: TargetOrigin,
76    #[serde(default)]
77    pub header_source: HeaderSource,
78    #[serde(default)]
79    pub header_sync: Option<HeaderSyncSnapshot>,
80}
81
82#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
83pub struct PackageSnapshot {
84    pub package: String,
85    pub manifest_path: String,
86    pub crate_types: Vec<String>,
87    #[serde(default)]
88    pub types: Vec<TypeDeclaration>,
89    pub headers: Vec<HeaderDeclaration>,
90    pub exports: Vec<ExportRecord>,
91    #[serde(default)]
92    pub artifacts: Vec<BinaryArtifactSnapshot>,
93}
94
95#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
96pub struct HeaderDeclaration {
97    pub path: String,
98    #[serde(default = "default_header_line")]
99    pub line: usize,
100    pub name: String,
101    pub signature: String,
102    #[serde(default)]
103    pub normalized_signature: Option<String>,
104    #[serde(default)]
105    pub return_type: Option<String>,
106    #[serde(default)]
107    pub param_types: Vec<String>,
108}
109
110#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
111pub struct ExportRecord {
112    pub rust_name: String,
113    pub export_name: String,
114    pub abi: String,
115    pub signature: String,
116    #[serde(default)]
117    pub normalized_signature: Option<String>,
118    #[serde(default)]
119    pub return_type: Option<String>,
120    #[serde(default)]
121    pub param_types: Vec<String>,
122    pub file: String,
123    pub line: usize,
124    pub has_stable_export_attr: bool,
125    pub export_attr: Option<String>,
126    pub opaque_handle_types: Vec<String>,
127}
128
129#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
130pub struct HeaderSyncSnapshot {
131    pub tool: HeaderSyncTool,
132    pub output: String,
133    pub crate_dir: String,
134    pub command: String,
135    #[serde(default)]
136    pub config: Option<String>,
137    #[serde(default)]
138    pub output_exists: bool,
139    #[serde(default)]
140    pub config_exists: bool,
141    #[serde(default)]
142    pub freshness_checked: bool,
143    #[serde(default)]
144    pub stale: bool,
145    #[serde(default)]
146    pub evidence: Vec<String>,
147}
148
149#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
150pub struct BinaryArtifactSnapshot {
151    pub path: String,
152    pub kind: ArtifactKind,
153    pub format: String,
154    #[serde(default)]
155    pub inspected: bool,
156    #[serde(default)]
157    pub inspector: Option<String>,
158    #[serde(default)]
159    pub exported_symbols: Vec<String>,
160    #[serde(default)]
161    pub notes: Vec<String>,
162}
163
164#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
165#[serde(rename_all = "snake_case")]
166pub enum TypeKind {
167    Struct,
168    Enum,
169    Union,
170    Alias,
171}
172
173#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
174pub struct TypeDeclaration {
175    pub name: String,
176    pub kind: TypeKind,
177    pub file: String,
178    pub line: usize,
179    #[serde(default)]
180    pub canonical_name: String,
181    #[serde(default)]
182    pub reprs: Vec<String>,
183    #[serde(default)]
184    pub fields: Vec<TypeMember>,
185    #[serde(default)]
186    pub fieldless: bool,
187    #[serde(default)]
188    pub by_value_ffi_safe: bool,
189    #[serde(default)]
190    pub by_value_notes: Vec<String>,
191}
192
193#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
194pub struct TypeMember {
195    pub name: Option<String>,
196    pub ty: String,
197}
198
199#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
200pub struct CheckReport {
201    pub snapshot: WorkspaceSnapshot,
202    pub findings: Vec<Finding>,
203    pub summary: CheckSummary,
204}
205
206#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
207pub struct CheckSummary {
208    pub packages_scanned: usize,
209    pub exports_scanned: usize,
210    pub warnings: usize,
211    pub errors: usize,
212}
213
214#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
215pub struct SnapshotRun {
216    pub snapshot: WorkspaceSnapshot,
217    pub output_path: Option<PathBuf>,
218}
219
220#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
221pub struct CheckResult {
222    pub report: CheckReport,
223    pub exit_code: i32,
224}
225
226const fn default_header_line() -> usize {
227    1
228}