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