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}