-
Couldn't load subscription status.
- Fork 13.9k
Description
Currently we use 3 different ways to serialse enums to json:
- For some of the enums, we use Adjacently tagged
rust/src/rustdoc-json-types/lib.rs
Lines 372 to 423 in 71226d7
| #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] | |
| #[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>), | |
| /// `_` | |
| 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>, | |
| }, | |
| } |
Which ends up looking like
"output": {
"inner": {
"lifetime": "'a",
"mutable": false,
"type": {"inner": "i32", "kind": "primitive"}
},
"kind": "borrowed_ref"
}- For others we use serdes default which is Externally tagged
rust/src/rustdoc-json-types/lib.rs
Lines 322 to 334 in 71226d7
| #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] | |
| pub struct GenericParamDef { | |
| pub name: String, | |
| pub kind: GenericParamDefKind, | |
| } | |
| #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] | |
| #[serde(rename_all = "snake_case")] | |
| pub enum GenericParamDefKind { | |
| Lifetime { outlives: Vec<String> }, | |
| Type { bounds: Vec<GenericBound>, default: Option<Type> }, | |
| Const { ty: Type, default: Option<String> }, | |
| } |
Which gives output that looks like
"params": [
{
"kind": {"lifetime": {"outlives": []}},
"name": "'a"
},
{
"kind": {"type": {"bounds": [], "default": null}},
"name": "T"
}- Finaly we have the
Item/ItemEnum, which are their own special weird, because of Remove Item::kind, use tagged enum. Rename variants to match #82613.
Its basicly Ajacenctly tagged, but the tag/content are inlined to the Item
I'm not sure how much it matters which one we pick as almost all users will be going through the rust types, but it would be good to be consistant. I have no prefernce between 1 and 2, but 3 seems weird, so I dont think we should do that.
cc @CraftSpider
@rustbot modify labels: +C-discussion +A-rustdoc-json +T-rustdoc
but I think 3 is bad