Skip to main content

substrate_data/schema/description/
definition_doc.rs

1//! [`DefinitionDoc`]: a struct's or an enum's definition as data.
2
3use super::definitions::Definitions;
4use super::{FieldDoc, ShapeNode, VariantDoc};
5use crate::schema::{EnumShape, StructShape};
6
7/// A struct or an enum, as written once in a description's `defs`.
8#[derive(Debug, Clone, PartialEq, crate::Schema)]
9#[data(tag = "kind")]
10pub enum DefinitionDoc {
11    /// A struct: an object of these fields.
12    Struct {
13        /// Its doc comment.
14        doc: Option<String>,
15        /// Its fields, in order.
16        fields: Vec<FieldDoc>,
17    },
18    /// An enum: one of these variants.
19    Enum {
20        /// Its doc comment.
21        doc: Option<String>,
22        /// The key naming the variant; none for an enum of names.
23        tag: Option<String>,
24        /// Its variants, in order.
25        variants: Vec<VariantDoc>,
26    },
27}
28
29impl DefinitionDoc {
30    /// `s` defined in `defs` (once), and a reference to it.
31    pub(super) fn define_struct(s: &StructShape, defs: &mut Definitions) -> ShapeNode {
32        if !defs.has(s.name) {
33            defs.reserve(s.name);
34            let fields = FieldDoc::all(&s.fields, defs);
35            let doc = non_empty(s.doc);
36            defs.set(s.name, DefinitionDoc::Struct { doc, fields });
37        }
38        ShapeNode::Def {
39            name: s.name.to_owned(),
40        }
41    }
42
43    /// `e` defined in `defs` (once), and a reference to it.
44    pub(super) fn define_enum(e: &EnumShape, defs: &mut Definitions) -> ShapeNode {
45        if !defs.has(e.name) {
46            defs.reserve(e.name);
47            let variants = e
48                .variants
49                .iter()
50                .map(|v| VariantDoc::of(v, e.tag.is_some(), defs))
51                .collect();
52            let definition = DefinitionDoc::Enum {
53                doc: non_empty(e.doc),
54                tag: e.tag.map(str::to_owned),
55                variants,
56            };
57            defs.set(e.name, definition);
58        }
59        ShapeNode::Def {
60            name: e.name.to_owned(),
61        }
62    }
63}
64
65/// A doc comment, none when it's empty.
66pub(super) fn non_empty(doc: &str) -> Option<String> {
67    (!doc.is_empty()).then(|| doc.to_owned())
68}