Skip to main content

substrate_data/schema/
shape.rs

1//! Shapes: what a format looks like.
2
3use super::named_type::NamedShape;
4
5// ── Shapes ──────────────────────────────────────────────────────────────────
6
7/// A shape, built on demand — so shapes of recursive types are fine.
8pub type ShapeFn = fn() -> Shape;
9
10/// What a format looks like: drives an editor's property grids and
11/// pickers, completion, hover docs and the docs' field tables.
12#[derive(Debug, Clone)]
13pub enum Shape {
14    /// Any value.
15    Any,
16    /// `true` or `false`.
17    Bool,
18    /// An integer in `min..=max`.
19    Int {
20        /// The smallest it takes.
21        min: i64,
22        /// The biggest it takes.
23        max: i64,
24    },
25    /// A number with a fraction, `bits` wide (32 or 64): how a frame packs it.
26    Float {
27        /// Its width: 32 or 64.
28        bits: u32,
29    },
30    /// Plain text.
31    Str,
32    /// A name that repeats ([`crate::Atom`]): text everywhere, its number in a frame.
33    Atom,
34    /// Bytes as they are.
35    Bytes,
36    /// A reference of one of `kinds` (`&[]`: any kind), written
37    /// `@kind:id`, its id of shape `id` (text, a number, a `uid`).
38    Ref {
39        /// The kinds it takes (any kind if empty), the first the one written.
40        kinds: &'static [&'static str],
41        /// The shape of its id.
42        id: ShapeFn,
43    },
44    /// A type of the format's own that tools may know by name (`color`,
45    /// `date`, `money`), stored as another shape: a tool that knows the
46    /// name shows its own editor, one that doesn't edits what it's stored as.
47    Named(NamedShape),
48    /// A list of the shape.
49    List(ShapeFn),
50    /// An object of any keys, every value this shape.
51    Map(ShapeFn),
52    /// A value or null.
53    Optional(ShapeFn),
54    /// A struct: an object of its fields.
55    Struct(StructShape),
56    /// An enum: a name, or a tagged object.
57    Enum(EnumShape),
58}
59
60/// A struct's shape: its fields.
61#[derive(Debug, Clone)]
62pub struct StructShape {
63    /// Its name in the docs.
64    pub name: &'static str,
65    /// Its docs.
66    pub doc: &'static str,
67    /// Its fields, in order.
68    pub fields: Vec<Field>,
69}
70
71/// A field of a struct (or of an enum's variant).
72#[derive(Debug, Clone)]
73pub struct Field {
74    /// Its key.
75    pub name: &'static str,
76    /// Its docs.
77    pub doc: &'static str,
78    /// Its shape.
79    pub shape: ShapeFn,
80    /// Must be written (no default).
81    pub required: bool,
82    /// The numbers it holds must be in `min..=max` (`#[data(range = "1..=99")]`).
83    pub range: Option<(f64, f64)>,
84}
85
86/// An enum's shape: its variants, and the key naming one if it's tagged.
87#[derive(Debug, Clone)]
88pub struct EnumShape {
89    /// Its name in the docs.
90    pub name: &'static str,
91    /// Its docs.
92    pub doc: &'static str,
93    /// The key naming the variant (`"type"`), `None` for an enum of names.
94    pub tag: Option<&'static str>,
95    /// Its variants, in order.
96    pub variants: Vec<Variant>,
97}
98
99/// A variant of an enum.
100#[derive(Debug, Clone)]
101pub struct Variant {
102    /// Its name as written.
103    pub name: &'static str,
104    /// Its docs.
105    pub doc: &'static str,
106    /// The variant's fields (none for a name).
107    pub fields: Vec<Field>,
108}
109
110impl Shape {
111    /// The shape of `T`, a type of the format's own ([`crate::schema::NamedType`]).
112    #[must_use]
113    pub fn named<T: super::NamedType>() -> Shape {
114        Shape::Named(NamedShape::of::<T>())
115    }
116
117    /// The shape as data, for tools in other languages (an IDE, a doc generator).
118    /// Structs and enums are written once in `defs` and referred to by name.
119    #[must_use]
120    pub fn describe(&self) -> super::ShapeDoc {
121        super::ShapeDoc::of(self)
122    }
123}