1 //! Rustdoc's JSON output interface 2 //! 3 //! These types are the public API exposed through the `--output-format json` flag. The [`Crate`] 4 //! struct is the root of the JSON blob and all other items are contained within. 5 6 use std::collections::{HashMap, HashSet}; 7 use std::path::PathBuf; 8 9 use serde::{Deserialize, Serialize}; 10 11 /// A `Crate` is the root of the emitted JSON blob. It contains all type/documentation information 12 /// about the language items in the local crate, as well as info about external items to allow 13 /// tools to find or link to them. 14 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 15 pub struct Crate { 16 /// The id of the root [`Module`] item of the local crate. 17 pub root: Id, 18 /// The version string given to `--crate-version`, if any. 19 pub crate_version: Option<String>, 20 /// Whether or not the output includes private items. 21 pub includes_private: bool, 22 /// A collection of all items in the local crate as well as some external traits and their 23 /// items that are referenced locally. 24 pub index: HashMap<Id, Item>, 25 /// Maps IDs to fully qualified paths and other info helpful for generating links. 26 pub paths: HashMap<Id, ItemSummary>, 27 /// Maps `crate_id` of items to a crate name and html_root_url if it exists. 28 pub external_crates: HashMap<u32, ExternalCrate>, 29 /// A single version number to be used in the future when making backwards incompatible changes 30 /// to the JSON output. 31 pub format_version: u32, 32 } 33 34 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 35 pub struct ExternalCrate { 36 pub name: String, 37 pub html_root_url: Option<String>, 38 } 39 40 /// For external (not defined in the local crate) items, you don't get the same level of 41 /// information. This struct should contain enough to generate a link/reference to the item in 42 /// question, or can be used by a tool that takes the json output of multiple crates to find 43 /// the actual item definition with all the relevant info. 44 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 45 pub struct ItemSummary { 46 /// Can be used to look up the name and html_root_url of the crate this item came from in the 47 /// `external_crates` map. 48 pub crate_id: u32, 49 /// The list of path components for the fully qualified path of this item (e.g. 50 /// `["std", "io", "lazy", "Lazy"]` for `std::io::lazy::Lazy`). 51 pub path: Vec<String>, 52 /// Whether this item is a struct, trait, macro, etc. 53 pub kind: ItemKind, 54 } 55 56 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 57 pub struct Item { 58 /// The unique identifier of this item. Can be used to find this item in various mappings. 59 pub id: Id, 60 /// This can be used as a key to the `external_crates` map of [`Crate`] to see which crate 61 /// this item came from. 62 pub crate_id: u32, 63 /// Some items such as impls don't have names. 64 pub name: Option<String>, 65 /// The source location of this item (absent if it came from a macro expansion or inline 66 /// assembly). 67 pub span: Option<Span>, 68 /// By default all documented items are public, but you can tell rustdoc to output private items 69 /// so this field is needed to differentiate. 70 pub visibility: Visibility, 71 /// The full markdown docstring of this item. Absent if there is no documentation at all, 72 /// Some("") if there is some documentation but it is empty (EG `#[doc = ""]`). 73 pub docs: Option<String>, 74 /// This mapping resolves [intra-doc links](https://github.com/rust-lang/rfcs/blob/master/text/1946-intra-rustdoc-links.md) from the docstring to their IDs 75 pub links: HashMap<String, Id>, 76 /// Stringified versions of the attributes on this item (e.g. `"#[inline]"`) 77 pub attrs: Vec<String>, 78 pub deprecation: Option<Deprecation>, 79 #[serde(flatten)] 80 pub inner: ItemEnum, 81 } 82 83 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 84 pub struct Span { 85 /// The path to the source file for this span relative to the path `rustdoc` was invoked with. 86 pub filename: PathBuf, 87 /// Zero indexed Line and Column of the first character of the `Span` 88 pub begin: (usize, usize), 89 /// Zero indexed Line and Column of the last character of the `Span` 90 pub end: (usize, usize), 91 } 92 93 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 94 pub struct Deprecation { 95 pub since: Option<String>, 96 pub note: Option<String>, 97 } 98 99 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 100 #[serde(rename_all = "snake_case")] 101 pub enum Visibility { 102 Public, 103 /// For the most part items are private by default. The exceptions are associated items of 104 /// public traits and variants of public enums. 105 Default, 106 Crate, 107 /// For `pub(in path)` visibility. `parent` is the module it's restricted to and `path` is how 108 /// that module was referenced (like `"super::super"` or `"crate::foo::bar"`). 109 Restricted { 110 parent: Id, 111 path: String, 112 }, 113 } 114 115 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 116 #[serde(rename_all = "snake_case")] 117 pub enum GenericArgs { 118 /// <'a, 32, B: Copy, C = u32> 119 AngleBracketed { args: Vec<GenericArg>, bindings: Vec<TypeBinding> }, 120 /// Fn(A, B) -> C 121 Parenthesized { inputs: Vec<Type>, output: Option<Type> }, 122 } 123 124 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 125 #[serde(rename_all = "snake_case")] 126 pub enum GenericArg { 127 Lifetime(String), 128 Type(Type), 129 Const(Constant), 130 Infer, 131 } 132 133 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 134 pub struct Constant { 135 #[serde(rename = "type")] 136 pub type_: Type, 137 pub expr: String, 138 pub value: Option<String>, 139 pub is_literal: bool, 140 } 141 142 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 143 pub struct TypeBinding { 144 pub name: String, 145 pub binding: TypeBindingKind, 146 } 147 148 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 149 #[serde(rename_all = "snake_case")] 150 pub enum TypeBindingKind { 151 Equality(Type), 152 Constraint(Vec<GenericBound>), 153 } 154 155 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] 156 pub struct Id(pub String); 157 158 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 159 #[serde(rename_all = "snake_case")] 160 pub enum ItemKind { 161 Module, 162 ExternCrate, 163 Import, 164 Struct, 165 StructField, 166 Union, 167 Enum, 168 Variant, 169 Function, 170 Typedef, 171 OpaqueTy, 172 Constant, 173 Trait, 174 TraitAlias, 175 Method, 176 Impl, 177 Static, 178 ForeignType, 179 Macro, 180 ProcAttribute, 181 ProcDerive, 182 AssocConst, 183 AssocType, 184 Primitive, 185 Keyword, 186 } 187 188 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 189 #[serde(tag = "kind", content = "inner", rename_all = "snake_case")] 190 pub enum ItemEnum { 191 Module(Module), 192 ExternCrate { 193 name: String, 194 rename: Option<String>, 195 }, 196 Import(Import), 197 198 Union(Union), 199 Struct(Struct), 200 StructField(Type), 201 Enum(Enum), 202 Variant(Variant), 203 204 Function(Function), 205 206 Trait(Trait), 207 TraitAlias(TraitAlias), 208 Method(Method), 209 Impl(Impl), 210 211 Typedef(Typedef), 212 OpaqueTy(OpaqueTy), 213 Constant(Constant), 214 215 Static(Static), 216 217 /// `type`s from an extern block 218 ForeignType, 219 220 /// Declarative macro_rules! macro 221 Macro(String), 222 ProcMacro(ProcMacro), 223 224 PrimitiveType(String), 225 226 AssocConst { 227 #[serde(rename = "type")] 228 type_: Type, 229 /// e.g. `const X: usize = 5;` 230 default: Option<String>, 231 }, 232 AssocType { 233 bounds: Vec<GenericBound>, 234 /// e.g. `type X = usize;` 235 default: Option<Type>, 236 }, 237 } 238 239 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 240 pub struct Module { 241 pub is_crate: bool, 242 pub items: Vec<Id>, 243 } 244 245 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 246 pub struct Union { 247 pub generics: Generics, 248 pub fields_stripped: bool, 249 pub fields: Vec<Id>, 250 pub impls: Vec<Id>, 251 } 252 253 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 254 pub struct Struct { 255 pub struct_type: StructType, 256 pub generics: Generics, 257 pub fields_stripped: bool, 258 pub fields: Vec<Id>, 259 pub impls: Vec<Id>, 260 } 261 262 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 263 pub struct Enum { 264 pub generics: Generics, 265 pub variants_stripped: bool, 266 pub variants: Vec<Id>, 267 pub impls: Vec<Id>, 268 } 269 270 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 271 #[serde(rename_all = "snake_case")] 272 #[serde(tag = "variant_kind", content = "variant_inner")] 273 pub enum Variant { 274 Plain, 275 Tuple(Vec<Type>), 276 Struct(Vec<Id>), 277 } 278 279 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 280 #[serde(rename_all = "snake_case")] 281 pub enum StructType { 282 Plain, 283 Tuple, 284 Unit, 285 } 286 287 #[non_exhaustive] 288 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)] 289 #[serde(rename_all = "snake_case")] 290 pub enum Qualifiers { 291 Const, 292 Unsafe, 293 Async, 294 } 295 296 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 297 pub struct Function { 298 pub decl: FnDecl, 299 pub generics: Generics, 300 pub header: HashSet<Qualifiers>, 301 pub abi: String, 302 } 303 304 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 305 pub struct Method { 306 pub decl: FnDecl, 307 pub generics: Generics, 308 pub header: HashSet<Qualifiers>, 309 pub abi: String, 310 pub has_body: bool, 311 } 312 313 #[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)] 314 pub struct Generics { 315 pub params: Vec<GenericParamDef>, 316 pub where_predicates: Vec<WherePredicate>, 317 } 318 319 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 320 pub struct GenericParamDef { 321 pub name: String, 322 pub kind: GenericParamDefKind, 323 } 324 325 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 326 #[serde(rename_all = "snake_case")] 327 pub enum GenericParamDefKind { 328 Lifetime { outlives: Vec<String> }, 329 Type { bounds: Vec<GenericBound>, default: Option<Type> }, 330 Const { ty: Type, default: Option<String> }, 331 } 332 333 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 334 #[serde(rename_all = "snake_case")] 335 pub enum WherePredicate { 336 BoundPredicate { ty: Type, bounds: Vec<GenericBound> }, 337 RegionPredicate { lifetime: String, bounds: Vec<GenericBound> }, 338 EqPredicate { lhs: Type, rhs: Type }, 339 } 340 341 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 342 #[serde(rename_all = "snake_case")] 343 pub enum GenericBound { 344 TraitBound { 345 #[serde(rename = "trait")] 346 trait_: Type, 347 /// Used for HRTBs 348 generic_params: Vec<GenericParamDef>, 349 modifier: TraitBoundModifier, 350 }, 351 Outlives(String), 352 } 353 354 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 355 #[serde(rename_all = "snake_case")] 356 pub enum TraitBoundModifier { 357 None, 358 Maybe, 359 MaybeConst, 360 } 361 362 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 363 #[serde(rename_all = "snake_case")] 364 #[serde(tag = "kind", content = "inner")] 365 pub enum Type { 366 /// Structs, enums, and traits 367 ResolvedPath { 368 name: String, 369 id: Id, 370 args: Option<Box<GenericArgs>>, 371 param_names: Vec<GenericBound>, 372 }, 373 /// Parameterized types 374 Generic(String), 375 /// Fixed-size numeric types (plus int/usize/float), char, arrays, slices, and tuples 376 Primitive(String), 377 /// `extern "ABI" fn` 378 FunctionPointer(Box<FunctionPointer>), 379 /// `(String, u32, Box<usize>)` 380 Tuple(Vec<Type>), 381 /// `[u32]` 382 Slice(Box<Type>), 383 /// [u32; 15] 384 Array { 385 #[serde(rename = "type")] 386 type_: Box<Type>, 387 len: String, 388 }, 389 /// `impl TraitA + TraitB + ...` 390 ImplTrait(Vec<GenericBound>), 391 /// `_` 392 Infer, 393 /// `*mut u32`, `*u8`, etc. 394 RawPointer { 395 mutable: bool, 396 #[serde(rename = "type")] 397 type_: Box<Type>, 398 }, 399 /// `&'a mut String`, `&str`, etc. 400 BorrowedRef { 401 lifetime: Option<String>, 402 mutable: bool, 403 #[serde(rename = "type")] 404 type_: Box<Type>, 405 }, 406 /// `<Type as Trait>::Name` or associated types like `T::Item` where `T: Iterator` 407 QualifiedPath { 408 name: String, 409 self_type: Box<Type>, 410 #[serde(rename = "trait")] 411 trait_: Box<Type>, 412 }, 413 } 414 415 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 416 pub struct FunctionPointer { 417 pub decl: FnDecl, 418 pub generic_params: Vec<GenericParamDef>, 419 pub header: HashSet<Qualifiers>, 420 pub abi: String, 421 } 422 423 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 424 pub struct FnDecl { 425 pub inputs: Vec<(String, Type)>, 426 pub output: Option<Type>, 427 pub c_variadic: bool, 428 } 429 430 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 431 pub struct Trait { 432 pub is_auto: bool, 433 pub is_unsafe: bool, 434 pub items: Vec<Id>, 435 pub generics: Generics, 436 pub bounds: Vec<GenericBound>, 437 pub implementors: Vec<Id>, 438 } 439 440 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 441 pub struct TraitAlias { 442 pub generics: Generics, 443 pub params: Vec<GenericBound>, 444 } 445 446 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 447 pub struct Impl { 448 pub is_unsafe: bool, 449 pub generics: Generics, 450 pub provided_trait_methods: Vec<String>, 451 #[serde(rename = "trait")] 452 pub trait_: Option<Type>, 453 #[serde(rename = "for")] 454 pub for_: Type, 455 pub items: Vec<Id>, 456 pub negative: bool, 457 pub synthetic: bool, 458 pub blanket_impl: Option<Type>, 459 } 460 461 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 462 #[serde(rename_all = "snake_case")] 463 pub struct Import { 464 /// The full path being imported. 465 pub source: String, 466 /// May be different from the last segment of `source` when renaming imports: 467 /// `use source as name;` 468 pub name: String, 469 /// The ID of the item being imported. 470 pub id: Option<Id>, // FIXME is this actually ever None? 471 /// Whether this import uses a glob: `use source::*;` 472 pub glob: bool, 473 } 474 475 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 476 pub struct ProcMacro { 477 pub kind: MacroKind, 478 pub helpers: Vec<String>, 479 } 480 481 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 482 #[serde(rename_all = "snake_case")] 483 pub enum MacroKind { 484 /// A bang macro `foo!()`. 485 Bang, 486 /// An attribute macro `#[foo]`. 487 Attr, 488 /// A derive macro `#[derive(Foo)]` 489 Derive, 490 } 491 492 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 493 pub struct Typedef { 494 #[serde(rename = "type")] 495 pub type_: Type, 496 pub generics: Generics, 497 } 498 499 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 500 pub struct OpaqueTy { 501 pub bounds: Vec<GenericBound>, 502 pub generics: Generics, 503 } 504 505 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 506 pub struct Static { 507 #[serde(rename = "type")] 508 pub type_: Type, 509 pub mutable: bool, 510 pub expr: String, 511 } 512 513 /// rustdoc format-version. 514 pub const FORMAT_VERSION: u32 = 9; 515 516 #[cfg(test)] 517 mod tests; 518