2020-08-03 12:45:27 -05:00
//! Rustdoc's JSON output interface
//!
//! These types are the public API exposed through the `--output-format json` flag. The [`Crate`]
//! struct is the root of the JSON blob and all other items are contained within.
2021-02-08 16:04:14 -05:00
use std ::collections ::{ HashMap , HashSet } ;
2020-08-03 12:45:27 -05:00
use std ::path ::PathBuf ;
use serde ::{ Deserialize , Serialize } ;
/// A `Crate` is the root of the emitted JSON blob. It contains all type/documentation information
/// about the language items in the local crate, as well as info about external items to allow
/// tools to find or link to them.
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-08-03 12:45:27 -05:00
pub struct Crate {
/// The id of the root [`Module`] item of the local crate.
pub root : Id ,
/// The version string given to `--crate-version`, if any.
pub crate_version : Option < String > ,
/// Whether or not the output includes private items.
pub includes_private : bool ,
/// A collection of all items in the local crate as well as some external traits and their
/// items that are referenced locally.
2021-01-22 16:09:24 -05:00
pub index : HashMap < Id , Item > ,
2020-08-03 12:45:27 -05:00
/// Maps IDs to fully qualified paths and other info helpful for generating links.
2021-01-22 16:09:24 -05:00
pub paths : HashMap < Id , ItemSummary > ,
2020-08-03 12:45:27 -05:00
/// Maps `crate_id` of items to a crate name and html_root_url if it exists.
2021-01-22 16:09:24 -05:00
pub external_crates : HashMap < u32 , ExternalCrate > ,
2020-08-03 12:45:27 -05:00
/// A single version number to be used in the future when making backwards incompatible changes
/// to the JSON output.
pub format_version : u32 ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-08-03 12:45:27 -05:00
pub struct ExternalCrate {
pub name : String ,
pub html_root_url : Option < String > ,
}
/// For external (not defined in the local crate) items, you don't get the same level of
/// information. This struct should contain enough to generate a link/reference to the item in
/// question, or can be used by a tool that takes the json output of multiple crates to find
/// the actual item definition with all the relevant info.
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-08-03 12:45:27 -05:00
pub struct ItemSummary {
/// Can be used to look up the name and html_root_url of the crate this item came from in the
/// `external_crates` map.
pub crate_id : u32 ,
/// The list of path components for the fully qualified path of this item (e.g.
/// `["std", "io", "lazy", "Lazy"]` for `std::io::lazy::Lazy`).
pub path : Vec < String > ,
/// Whether this item is a struct, trait, macro, etc.
pub kind : ItemKind ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-08-03 12:45:27 -05:00
pub struct Item {
/// The unique identifier of this item. Can be used to find this item in various mappings.
pub id : Id ,
/// This can be used as a key to the `external_crates` map of [`Crate`] to see which crate
/// this item came from.
pub crate_id : u32 ,
/// Some items such as impls don't have names.
pub name : Option < String > ,
/// The source location of this item (absent if it came from a macro expansion or inline
/// assembly).
pub source : Option < Span > ,
/// By default all documented items are public, but you can tell rustdoc to output private items
/// so this field is needed to differentiate.
pub visibility : Visibility ,
2021-01-20 17:52:52 -05:00
/// The full markdown docstring of this item. Absent if there is no documentation at all,
/// Some("") if there is some documentation but it is empty (EG `#[doc = ""]`).
2021-01-20 15:58:03 -05:00
pub docs : Option < String > ,
2020-08-03 12:45:27 -05:00
/// 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
2021-01-22 16:09:24 -05:00
pub links : HashMap < String , Id > ,
2020-08-03 12:45:27 -05:00
/// Stringified versions of the attributes on this item (e.g. `"#[inline]"`)
pub attrs : Vec < String > ,
pub deprecation : Option < Deprecation > ,
2021-02-27 19:44:17 -05:00
#[ serde(flatten) ]
2020-08-03 12:45:27 -05:00
pub inner : ItemEnum ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-08-03 12:45:27 -05:00
pub struct Span {
/// The path to the source file for this span relative to the path `rustdoc` was invoked with.
pub filename : PathBuf ,
/// Zero indexed Line and Column of the first character of the `Span`
pub begin : ( usize , usize ) ,
/// Zero indexed Line and Column of the last character of the `Span`
pub end : ( usize , usize ) ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-08-03 12:45:27 -05:00
pub struct Deprecation {
pub since : Option < String > ,
pub note : Option < String > ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-11-14 14:47:14 +03:00
#[ serde(rename_all = " snake_case " ) ]
2020-08-03 12:45:27 -05:00
pub enum Visibility {
Public ,
/// For the most part items are private by default. The exceptions are associated items of
/// public traits and variants of public enums.
Default ,
Crate ,
/// For `pub(in path)` visibility. `parent` is the module it's restricted to and `path` is how
/// that module was referenced (like `"super::super"` or `"crate::foo::bar"`).
Restricted {
parent : Id ,
path : String ,
} ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-11-14 14:47:14 +03:00
#[ serde(rename_all = " snake_case " ) ]
2020-08-03 12:45:27 -05:00
pub enum GenericArgs {
/// <'a, 32, B: Copy, C = u32>
AngleBracketed { args : Vec < GenericArg > , bindings : Vec < TypeBinding > } ,
/// Fn(A, B) -> C
Parenthesized { inputs : Vec < Type > , output : Option < Type > } ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-11-14 14:47:14 +03:00
#[ serde(rename_all = " snake_case " ) ]
2020-08-03 12:45:27 -05:00
pub enum GenericArg {
Lifetime ( String ) ,
Type ( Type ) ,
Const ( Constant ) ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-08-03 12:45:27 -05:00
pub struct Constant {
#[ serde(rename = " type " ) ]
pub type_ : Type ,
pub expr : String ,
pub value : Option < String > ,
pub is_literal : bool ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-08-03 12:45:27 -05:00
pub struct TypeBinding {
pub name : String ,
pub binding : TypeBindingKind ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-11-14 14:47:14 +03:00
#[ serde(rename_all = " snake_case " ) ]
2020-08-03 12:45:27 -05:00
pub enum TypeBindingKind {
Equality ( Type ) ,
Constraint ( Vec < GenericBound > ) ,
}
#[ derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize) ]
pub struct Id ( pub String ) ;
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-11-14 14:47:14 +03:00
#[ serde(rename_all = " snake_case " ) ]
2020-08-03 12:45:27 -05:00
pub enum ItemKind {
Module ,
ExternCrate ,
Import ,
Struct ,
StructField ,
Union ,
Enum ,
Variant ,
Function ,
Typedef ,
OpaqueTy ,
Constant ,
Trait ,
TraitAlias ,
Method ,
Impl ,
Static ,
ForeignType ,
Macro ,
ProcAttribute ,
ProcDerive ,
AssocConst ,
AssocType ,
Primitive ,
Keyword ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2021-02-27 19:44:17 -05:00
#[ serde(tag = " kind " , content = " inner " , rename_all = " snake_case " ) ]
2020-08-03 12:45:27 -05:00
pub enum ItemEnum {
2021-02-27 19:44:17 -05:00
Module ( Module ) ,
ExternCrate {
2020-08-03 12:45:27 -05:00
name : String ,
rename : Option < String > ,
} ,
2021-02-27 19:44:17 -05:00
Import ( Import ) ,
2020-08-03 12:45:27 -05:00
2021-02-27 19:44:17 -05:00
Union ( Union ) ,
Struct ( Struct ) ,
StructField ( Type ) ,
Enum ( Enum ) ,
Variant ( Variant ) ,
2020-08-03 12:45:27 -05:00
2021-02-27 19:44:17 -05:00
Function ( Function ) ,
2020-08-03 12:45:27 -05:00
2021-02-27 19:44:17 -05:00
Trait ( Trait ) ,
TraitAlias ( TraitAlias ) ,
Method ( Method ) ,
Impl ( Impl ) ,
2020-08-03 12:45:27 -05:00
2021-02-27 19:44:17 -05:00
Typedef ( Typedef ) ,
OpaqueTy ( OpaqueTy ) ,
Constant ( Constant ) ,
2020-08-03 12:45:27 -05:00
2021-02-27 19:44:17 -05:00
Static ( Static ) ,
2020-08-03 12:45:27 -05:00
/// `type`s from an extern block
2021-02-27 19:44:17 -05:00
ForeignType ,
2020-08-03 12:45:27 -05:00
/// Declarative macro_rules! macro
2021-02-27 19:44:17 -05:00
Macro ( String ) ,
ProcMacro ( ProcMacro ) ,
2020-08-03 12:45:27 -05:00
2021-02-27 19:44:17 -05:00
AssocConst {
2020-08-03 12:45:27 -05:00
#[ serde(rename = " type " ) ]
type_ : Type ,
/// e.g. `const X: usize = 5;`
default : Option < String > ,
} ,
2021-02-27 19:44:17 -05:00
AssocType {
2020-08-03 12:45:27 -05:00
bounds : Vec < GenericBound > ,
/// e.g. `type X = usize;`
default : Option < Type > ,
} ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-08-03 12:45:27 -05:00
pub struct Module {
pub is_crate : bool ,
pub items : Vec < Id > ,
}
2021-01-23 19:40:29 -05:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
pub struct Union {
pub generics : Generics ,
pub fields_stripped : bool ,
pub fields : Vec < Id > ,
pub impls : Vec < Id > ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-08-03 12:45:27 -05:00
pub struct Struct {
pub struct_type : StructType ,
pub generics : Generics ,
pub fields_stripped : bool ,
pub fields : Vec < Id > ,
pub impls : Vec < Id > ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-08-03 12:45:27 -05:00
pub struct Enum {
pub generics : Generics ,
pub variants_stripped : bool ,
pub variants : Vec < Id > ,
pub impls : Vec < Id > ,
}
2020-11-14 14:47:14 +03:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-08-03 12:45:27 -05:00
#[ serde(rename_all = " snake_case " ) ]
#[ serde(tag = " variant_kind " , content = " variant_inner " ) ]
pub enum Variant {
Plain ,
Tuple ( Vec < Type > ) ,
Struct ( Vec < Id > ) ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-11-14 14:47:14 +03:00
#[ serde(rename_all = " snake_case " ) ]
2020-08-03 12:45:27 -05:00
pub enum StructType {
Plain ,
Tuple ,
Unit ,
}
2021-02-08 13:48:10 -05:00
#[ non_exhaustive ]
2021-02-08 16:04:14 -05:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash) ]
2021-02-08 15:45:50 -05:00
#[ serde(rename_all = " snake_case " ) ]
2021-02-12 23:24:09 -05:00
pub enum Qualifiers {
2021-02-08 13:48:10 -05:00
Const ,
Unsafe ,
Async ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-08-03 12:45:27 -05:00
pub struct Function {
pub decl : FnDecl ,
pub generics : Generics ,
2021-02-12 23:24:09 -05:00
pub header : HashSet < Qualifiers > ,
2020-08-03 12:45:27 -05:00
pub abi : String ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-08-03 12:45:27 -05:00
pub struct Method {
pub decl : FnDecl ,
pub generics : Generics ,
2021-02-12 23:24:09 -05:00
pub header : HashSet < Qualifiers > ,
2021-01-29 01:07:50 -05:00
pub abi : String ,
2020-08-03 12:45:27 -05:00
pub has_body : bool ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq) ]
2020-08-03 12:45:27 -05:00
pub struct Generics {
pub params : Vec < GenericParamDef > ,
pub where_predicates : Vec < WherePredicate > ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-08-03 12:45:27 -05:00
pub struct GenericParamDef {
pub name : String ,
pub kind : GenericParamDefKind ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-11-14 14:47:14 +03:00
#[ serde(rename_all = " snake_case " ) ]
2020-08-03 12:45:27 -05:00
pub enum GenericParamDefKind {
Lifetime ,
Type { bounds : Vec < GenericBound > , default : Option < Type > } ,
Const ( Type ) ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-11-14 14:47:14 +03:00
#[ serde(rename_all = " snake_case " ) ]
2020-08-03 12:45:27 -05:00
pub enum WherePredicate {
BoundPredicate { ty : Type , bounds : Vec < GenericBound > } ,
RegionPredicate { lifetime : String , bounds : Vec < GenericBound > } ,
EqPredicate { lhs : Type , rhs : Type } ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-11-14 14:47:14 +03:00
#[ serde(rename_all = " snake_case " ) ]
2020-08-03 12:45:27 -05:00
pub enum GenericBound {
TraitBound {
#[ serde(rename = " trait " ) ]
trait_ : Type ,
/// Used for HRTBs
generic_params : Vec < GenericParamDef > ,
modifier : TraitBoundModifier ,
} ,
Outlives ( String ) ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-11-14 14:47:14 +03:00
#[ serde(rename_all = " snake_case " ) ]
2020-08-03 12:45:27 -05:00
pub enum TraitBoundModifier {
None ,
Maybe ,
MaybeConst ,
}
2020-11-14 14:47:14 +03:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-08-03 12:45:27 -05:00
#[ serde(rename_all = " snake_case " ) ]
#[ serde(tag = " kind " , content = " inner " ) ]
pub enum Type {
/// Structs, enums, and traits
ResolvedPath {
name : String ,
id : Id ,
args : Option < Box < GenericArgs > > ,
param_names : Vec < GenericBound > ,
} ,
/// Parameterized types
Generic ( String ) ,
/// Fixed-size numeric types (plus int/usize/float), char, arrays, slices, and tuples
Primitive ( String ) ,
/// `extern "ABI" fn`
FunctionPointer ( Box < FunctionPointer > ) ,
/// `(String, u32, Box<usize>)`
Tuple ( Vec < Type > ) ,
/// `[u32]`
Slice ( Box < Type > ) ,
/// [u32; 15]
Array {
#[ serde(rename = " type " ) ]
type_ : Box < Type > ,
len : String ,
} ,
/// `impl TraitA + TraitB + ...`
ImplTrait ( Vec < GenericBound > ) ,
/// `!`
Never ,
/// `_`
Infer ,
/// `*mut u32`, `*u8`, etc.
RawPointer {
mutable : bool ,
#[ serde(rename = " type " ) ]
type_ : Box < Type > ,
} ,
/// `&'a mut String`, `&str`, etc.
BorrowedRef {
lifetime : Option < String > ,
mutable : bool ,
#[ serde(rename = " type " ) ]
type_ : Box < Type > ,
} ,
/// `<Type as Trait>::Name` or associated types like `T::Item` where `T: Iterator`
QualifiedPath {
name : String ,
self_type : Box < Type > ,
#[ serde(rename = " trait " ) ]
trait_ : Box < Type > ,
} ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-08-03 12:45:27 -05:00
pub struct FunctionPointer {
pub decl : FnDecl ,
2021-02-08 13:48:10 -05:00
pub generic_params : Vec < GenericParamDef > ,
2021-02-12 23:24:09 -05:00
pub header : HashSet < Qualifiers > ,
2020-08-03 12:45:27 -05:00
pub abi : String ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-08-03 12:45:27 -05:00
pub struct FnDecl {
pub inputs : Vec < ( String , Type ) > ,
pub output : Option < Type > ,
pub c_variadic : bool ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-08-03 12:45:27 -05:00
pub struct Trait {
pub is_auto : bool ,
pub is_unsafe : bool ,
pub items : Vec < Id > ,
pub generics : Generics ,
pub bounds : Vec < GenericBound > ,
pub implementors : Vec < Id > ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-08-03 12:45:27 -05:00
pub struct TraitAlias {
pub generics : Generics ,
pub params : Vec < GenericBound > ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-08-03 12:45:27 -05:00
pub struct Impl {
pub is_unsafe : bool ,
pub generics : Generics ,
pub provided_trait_methods : Vec < String > ,
#[ serde(rename = " trait " ) ]
pub trait_ : Option < Type > ,
#[ serde(rename = " for " ) ]
pub for_ : Type ,
pub items : Vec < Id > ,
pub negative : bool ,
pub synthetic : bool ,
pub blanket_impl : Option < Type > ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-11-14 14:47:14 +03:00
#[ serde(rename_all = " snake_case " ) ]
2020-08-03 12:45:27 -05:00
pub struct Import {
/// The full path being imported.
pub span : String ,
/// May be different from the last segment of `source` when renaming imports:
/// `use source as name;`
pub name : String ,
/// The ID of the item being imported.
pub id : Option < Id > , // FIXME is this actually ever None?
/// Whether this import uses a glob: `use source::*;`
pub glob : bool ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-08-03 12:45:27 -05:00
pub struct ProcMacro {
pub kind : MacroKind ,
pub helpers : Vec < String > ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-11-14 14:47:14 +03:00
#[ serde(rename_all = " snake_case " ) ]
2020-08-03 12:45:27 -05:00
pub enum MacroKind {
/// A bang macro `foo!()`.
Bang ,
/// An attribute macro `#[foo]`.
Attr ,
/// A derive macro `#[derive(Foo)]`
Derive ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-08-03 12:45:27 -05:00
pub struct Typedef {
#[ serde(rename = " type " ) ]
pub type_ : Type ,
pub generics : Generics ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-08-03 12:45:27 -05:00
pub struct OpaqueTy {
pub bounds : Vec < GenericBound > ,
pub generics : Generics ,
}
2020-12-05 22:23:17 +00:00
#[ derive(Clone, Debug, Serialize, Deserialize, PartialEq) ]
2020-08-03 12:45:27 -05:00
pub struct Static {
#[ serde(rename = " type " ) ]
pub type_ : Type ,
pub mutable : bool ,
pub expr : String ,
}
2021-03-04 18:45:57 -05:00
#[ cfg(test) ]
2021-03-04 19:08:06 -05:00
mod tests ;