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}