Skip to main content

sourcey_rustdoc/
spec.rs

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    /// Diagnostics that apply to the whole snapshot rather than any single
16    /// crate (e.g. `RUSTDOC_FORMAT_VERSION_MISMATCH`).
17    #[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    /// Item id (string) → Item. Stable lookup keyed by rustdoc's per-snapshot id.
28    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    /// Intra-doc link table: link label as it appears in the docstring,
69    /// mapped to a resolved target. Internal targets reference a local
70    /// item id; external targets carry enough metadata to render a docs.rs
71    /// or std URL without a second snapshot lookup.
72    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}