1use serde::{Deserialize, Serialize};
2use std::collections::BTreeMap;
3
4pub const SPEC_VERSION: u32 = 1;
5pub const SOURCEY_RUSTDOC_VERSION: &str = env!("CARGO_PKG_VERSION");
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct RustdocSpec {
9 pub version: u32,
10 pub sourcey_rustdoc_version: String,
11 pub rustdoc_format_version: u32,
12 pub rust_toolchain: String,
13 pub generated_at: String,
14 pub crates: Vec<CrateSpec>,
15 #[serde(default)]
18 pub diagnostics: Vec<Diagnostic>,
19}
20
21#[derive(Debug, Clone, Serialize, Deserialize)]
22pub struct CrateSpec {
23 pub name: String,
24 pub version: Option<String>,
25 pub root_module_id: ItemId,
26 pub modules: Vec<ModuleSpec>,
27 pub items: BTreeMap<String, Item>,
29 pub external_crates: Vec<ExternalCrateRef>,
30 pub diagnostics: Vec<Diagnostic>,
31}
32
33#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
34#[serde(transparent)]
35pub struct ItemId(pub String);
36
37#[derive(Debug, Clone, Serialize, Deserialize)]
38pub struct ModuleSpec {
39 pub id: ItemId,
40 pub path: Vec<String>,
41 pub docs_markdown: Option<String>,
42 pub doc_aliases: Vec<String>,
43 pub item_ids: Vec<ItemId>,
44 pub sub_module_paths: Vec<Vec<String>>,
45 pub source: Option<SourceLocation>,
46}
47
48#[derive(Debug, Clone, Serialize, Deserialize)]
49pub struct SourceLocation {
50 pub file: String,
51 pub line_start: u32,
52 pub line_end: u32,
53}
54
55#[derive(Debug, Clone, Serialize, Deserialize)]
56pub struct Item {
57 pub id: ItemId,
58 pub name: Option<String>,
59 pub path: Vec<String>,
60 pub visibility: Visibility,
61 pub source: Option<SourceLocation>,
62 pub docs_markdown: Option<String>,
63 pub doc_aliases: Vec<String>,
64 pub deprecation: Option<Deprecation>,
65 pub stability: Option<Stability>,
66 pub feature_gates: Vec<String>,
67 pub attrs_structured: Vec<String>,
68 pub links: BTreeMap<String, LinkTarget>,
73 pub inner: ItemInner,
74 pub doctests: Vec<Doctest>,
75}
76
77#[derive(Debug, Clone, Serialize, Deserialize)]
78#[serde(tag = "kind", rename_all = "snake_case")]
79pub enum Visibility {
80 Public,
81 Crate,
82 Restricted { path: String },
83 Default,
84}
85
86#[derive(Debug, Clone, Serialize, Deserialize)]
87pub struct Deprecation {
88 pub since: Option<String>,
89 pub note: Option<String>,
90}
91
92#[derive(Debug, Clone, Serialize, Deserialize)]
93pub struct Stability {
94 pub level: StabilityLevel,
95 pub since: Option<String>,
96 pub feature: Option<String>,
97 pub issue: Option<u32>,
98}
99
100#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
101#[serde(rename_all = "snake_case")]
102pub enum StabilityLevel {
103 Stable,
104 Unstable,
105}
106
107#[derive(Debug, Clone, Serialize, Deserialize)]
108#[serde(tag = "kind", rename_all = "snake_case")]
109pub enum ItemInner {
110 Function(FunctionItem),
111 Struct(StructItem),
112 Enum(EnumItem),
113 Variant(VariantItem),
114 Union(UnionItem),
115 Trait(TraitItem),
116 TraitAlias(TraitAliasItem),
117 Impl(ImplItem),
118 TypeAlias(TypeAliasItem),
119 Constant(ConstantItem),
120 Static(StaticItem),
121 Macro(MacroItem),
122 ProcMacro(ProcMacroItem),
123 AssocType(AssocTypeItem),
124 AssocConst(AssocConstItem),
125 Use(UseItem),
126 StructField(StructFieldItem),
127 Module,
128 Primitive,
129 ExternType,
130}
131
132#[derive(Debug, Clone, Serialize, Deserialize)]
133pub struct FunctionItem {
134 pub signature: Signature,
135 pub generics: Generics,
136 pub is_const: bool,
137 pub is_async: bool,
138 pub is_unsafe: bool,
139 pub has_body: bool,
140}
141
142#[derive(Debug, Clone, Serialize, Deserialize)]
143pub struct StructItem {
144 pub struct_kind: StructKindKind,
145 pub generics: Generics,
146 pub fields: Vec<ItemId>,
147 pub has_stripped_fields: bool,
148 pub impls: Vec<ItemId>,
149}
150
151#[derive(Debug, Clone, Serialize, Deserialize)]
152#[serde(rename_all = "snake_case")]
153pub enum StructKindKind {
154 Plain,
155 Tuple,
156 Unit,
157}
158
159#[derive(Debug, Clone, Serialize, Deserialize)]
160pub struct EnumItem {
161 pub generics: Generics,
162 pub variants: Vec<ItemId>,
163 pub has_stripped_variants: bool,
164 pub impls: Vec<ItemId>,
165}
166
167#[derive(Debug, Clone, Serialize, Deserialize)]
168pub struct VariantItem {
169 pub variant_kind: VariantKindKind,
170 pub discriminant: Option<String>,
171}
172
173#[derive(Debug, Clone, Serialize, Deserialize)]
174#[serde(rename_all = "snake_case")]
175pub enum VariantKindKind {
176 Plain,
177 Tuple,
178 Struct,
179}
180
181#[derive(Debug, Clone, Serialize, Deserialize)]
182pub struct UnionItem {
183 pub generics: Generics,
184 pub fields: Vec<ItemId>,
185 pub has_stripped_fields: bool,
186 pub impls: Vec<ItemId>,
187}
188
189#[derive(Debug, Clone, Serialize, Deserialize)]
190pub struct TraitItem {
191 pub is_auto: bool,
192 pub is_unsafe: bool,
193 pub is_dyn_compatible: bool,
194 pub generics: Generics,
195 pub bounds: Vec<String>,
196 pub items: Vec<ItemId>,
197 pub implementations: Vec<ItemId>,
198}
199
200#[derive(Debug, Clone, Serialize, Deserialize)]
201pub struct TraitAliasItem {
202 pub generics: Generics,
203 pub bounds: Vec<String>,
204}
205
206#[derive(Debug, Clone, Serialize, Deserialize)]
207pub struct ImplItem {
208 pub generics: Generics,
209 pub trait_path: Option<TypePath>,
210 pub for_type: TypePath,
211 pub items: Vec<ItemId>,
212 pub is_negative: bool,
213 pub is_synthetic: bool,
214 pub is_blanket: bool,
215 pub provided_trait_methods: Vec<String>,
216}
217
218#[derive(Debug, Clone, Serialize, Deserialize)]
219pub struct TypeAliasItem {
220 pub aliased_type: TypePath,
221 pub generics: Generics,
222}
223
224#[derive(Debug, Clone, Serialize, Deserialize)]
225pub struct ConstantItem {
226 pub type_display: String,
227 pub expr: String,
228 pub value: Option<String>,
229 pub is_literal: bool,
230}
231
232#[derive(Debug, Clone, Serialize, Deserialize)]
233pub struct StaticItem {
234 pub type_display: String,
235 pub expr: String,
236 pub is_mutable: bool,
237 pub is_unsafe: bool,
238}
239
240#[derive(Debug, Clone, Serialize, Deserialize)]
241pub struct MacroItem {
242 pub source: String,
243}
244
245#[derive(Debug, Clone, Serialize, Deserialize)]
246pub struct ProcMacroItem {
247 pub macro_kind: ProcMacroKindKind,
248 pub helpers: Vec<String>,
249}
250
251#[derive(Debug, Clone, Serialize, Deserialize)]
252#[serde(rename_all = "snake_case")]
253pub enum ProcMacroKindKind {
254 Bang,
255 Attr,
256 Derive,
257}
258
259#[derive(Debug, Clone, Serialize, Deserialize)]
260pub struct AssocTypeItem {
261 pub generics: Generics,
262 pub bounds: Vec<String>,
263 pub default_display: Option<String>,
264}
265
266#[derive(Debug, Clone, Serialize, Deserialize)]
267pub struct AssocConstItem {
268 pub type_display: String,
269 pub default_display: Option<String>,
270}
271
272#[derive(Debug, Clone, Serialize, Deserialize)]
273pub struct UseItem {
274 pub source: String,
275 pub name: String,
276 pub target_id: Option<ItemId>,
277 pub is_glob: bool,
278}
279
280#[derive(Debug, Clone, Serialize, Deserialize)]
281pub struct StructFieldItem {
282 pub type_display: String,
283}
284
285#[derive(Debug, Clone, Serialize, Deserialize)]
286pub struct Signature {
287 pub display: String,
288 pub tokens: Vec<SigToken>,
289 pub inputs: Vec<SigInput>,
290 pub output_display: Option<String>,
291 pub is_c_variadic: bool,
292}
293
294#[derive(Debug, Clone, Serialize, Deserialize)]
295pub struct SigInput {
296 pub name: String,
297 pub type_display: String,
298}
299
300#[derive(Debug, Clone, Serialize, Deserialize)]
301#[serde(tag = "kind", rename_all = "snake_case")]
302pub enum SigToken {
303 Keyword { text: String },
304 Punct { text: String },
305 Generic { text: String },
306 Lifetime { text: String },
307 Type { text: String, target: Option<TypePath> },
308 Whitespace,
309 Newline,
310}
311
312#[derive(Debug, Clone, Serialize, Deserialize)]
313pub struct TypePath {
314 pub crate_id: u32,
315 pub path: Vec<String>,
316 pub display: String,
317 pub external: bool,
318 pub html_root_url: Option<String>,
319}
320
321#[derive(Debug, Clone, Serialize, Deserialize, Default)]
322pub struct Generics {
323 pub params: Vec<GenericParam>,
324 pub where_predicates: Vec<String>,
325}
326
327#[derive(Debug, Clone, Serialize, Deserialize)]
328pub struct GenericParam {
329 pub name: String,
330 pub kind: GenericParamKind,
331 pub default_display: Option<String>,
332 pub bounds: Vec<String>,
333}
334
335#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
336#[serde(rename_all = "snake_case")]
337pub enum GenericParamKind {
338 Lifetime,
339 Type,
340 Const,
341}
342
343#[derive(Debug, Clone, Serialize, Deserialize)]
344#[serde(tag = "kind", rename_all = "snake_case")]
345pub enum LinkTarget {
346 Internal {
347 id: ItemId,
348 },
349 External {
350 crate_name: String,
351 path: Vec<String>,
352 html_root_url: Option<String>,
353 },
354}
355
356#[derive(Debug, Clone, Serialize, Deserialize)]
357pub struct Doctest {
358 pub lang: String,
359 pub fence_attributes: Vec<String>,
360 pub display_code: String,
361 pub executable_code: String,
362 pub implicit_main_wrap: bool,
363 pub source: Option<SourceLocation>,
364 pub ordinal: u32,
365}
366
367#[derive(Debug, Clone, Serialize, Deserialize)]
368pub struct ExternalCrateRef {
369 pub crate_id: u32,
370 pub name: String,
371 pub html_root_url: Option<String>,
372}
373
374#[derive(Debug, Clone, Serialize, Deserialize)]
375pub struct Diagnostic {
376 pub severity: DiagnosticSeverity,
377 pub code: String,
378 pub message: String,
379 pub crate_name: Option<String>,
380 pub file: Option<String>,
381 pub line: Option<u32>,
382}
383
384#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
385#[serde(rename_all = "snake_case")]
386pub enum DiagnosticSeverity {
387 Error,
388 Warning,
389 Info,
390}