Skip to main content

substrate_data/schema/description/
shape_node.rs

1//! [`ShapeNode`]: one shape as data, written `{ kind: "…", … }`.
2
3use super::DefinitionDoc;
4use super::definitions::Definitions;
5use crate::model::value::KindName;
6use crate::schema::Shape;
7
8/// One shape as data, tagged by `kind`; a struct or enum is a `def`, its
9/// definition written once in the description's `defs`.
10#[derive(Debug, Clone, PartialEq, crate::Schema)]
11#[data(tag = "kind")]
12pub enum ShapeNode {
13    /// Any value.
14    Any,
15    /// `true` or `false`.
16    Bool,
17    /// An integer in `min..=max`.
18    Int {
19        /// The least it may be.
20        min: i64,
21        /// The most it may be.
22        max: i64,
23    },
24    /// A number with a fraction, `bits` wide.
25    Float {
26        /// 32 or 64.
27        bits: u32,
28    },
29    /// Plain text.
30    String,
31    /// A name that repeats.
32    Atom,
33    /// Bytes as they are.
34    Bytes,
35    /// A reference of one of `of` (any kind if empty), its id of shape `id`.
36    Ref {
37        /// The kinds it takes.
38        of: Vec<KindName>,
39        /// The shape of its id.
40        id: Box<ShapeNode>,
41    },
42    /// A type tools may know by `name`, stored as `of`.
43    Named {
44        /// What tools know it by.
45        name: String,
46        /// What it's stored as.
47        of: Box<ShapeNode>,
48    },
49    /// A list of `of`.
50    List {
51        /// Each item's shape.
52        of: Box<ShapeNode>,
53    },
54    /// An object of any keys, every value `of`.
55    Map {
56        /// Each value's shape.
57        of: Box<ShapeNode>,
58    },
59    /// `of` or null.
60    Optional {
61        /// The shape when it's there.
62        of: Box<ShapeNode>,
63    },
64    /// The struct or enum `name`, defined in `defs`.
65    Def {
66        /// Its name in `defs`.
67        name: String,
68    },
69}
70
71impl ShapeNode {
72    /// `shape` as data, its structs and enums defined in `defs`.
73    pub(super) fn of(shape: &Shape, defs: &mut Definitions) -> ShapeNode {
74        let mut inner = |s: Shape| Box::new(ShapeNode::of(&s, defs));
75        match shape {
76            Shape::Any => ShapeNode::Any,
77            Shape::Bool => ShapeNode::Bool,
78            Shape::Int { min, max } => ShapeNode::Int {
79                min: *min,
80                max: *max,
81            },
82            Shape::Float { bits } => ShapeNode::Float { bits: *bits },
83            Shape::Str => ShapeNode::String,
84            Shape::Atom => ShapeNode::Atom,
85            Shape::Bytes => ShapeNode::Bytes,
86            Shape::Ref { kinds, id } => ShapeNode::Ref {
87                of: kinds.iter().filter_map(|k| KindName::new(k).ok()).collect(),
88                id: inner(id()),
89            },
90            Shape::Named(n) => ShapeNode::Named {
91                name: n.name().to_owned(),
92                of: inner(n.stored()),
93            },
94            Shape::List(s) => ShapeNode::List { of: inner(s()) },
95            Shape::Map(s) => ShapeNode::Map { of: inner(s()) },
96            Shape::Optional(s) => ShapeNode::Optional { of: inner(s()) },
97            Shape::Struct(s) => DefinitionDoc::define_struct(s, defs),
98            Shape::Enum(e) => DefinitionDoc::define_enum(e, defs),
99        }
100    }
101}