schematic_types/
schema_type.rs

1use crate::Schematic;
2use crate::arrays::*;
3use crate::bools::*;
4use crate::enums::*;
5use crate::literals::*;
6use crate::numbers::*;
7use crate::objects::*;
8use crate::schema::*;
9use crate::strings::*;
10use crate::structs::*;
11use crate::tuples::*;
12use crate::unions::*;
13
14/// All possible types within a schema.
15#[derive(Clone, Debug, Default, PartialEq)]
16#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
17#[cfg_attr(feature = "serde", serde(tag = "type"))]
18pub enum SchemaType {
19    Null,
20    #[default]
21    Unknown,
22    Array(Box<ArrayType>),
23    Boolean(Box<BooleanType>),
24    Enum(Box<EnumType>),
25    Float(Box<FloatType>),
26    Integer(Box<IntegerType>),
27    Literal(Box<LiteralType>),
28    Object(Box<ObjectType>),
29    Reference(String),
30    Struct(Box<StructType>),
31    String(Box<StringType>),
32    Tuple(Box<TupleType>),
33    Union(Box<UnionType>),
34}
35
36impl SchemaType {
37    /// Return a `default` value from the inner schema type.
38    pub fn get_default(&self) -> Option<&LiteralValue> {
39        match self {
40            SchemaType::Boolean(inner) => inner.default.as_ref(),
41            SchemaType::Enum(inner) => {
42                if let Some(index) = &inner.default_index {
43                    if let Some(value) = inner.values.get(*index) {
44                        return Some(value);
45                    }
46                }
47
48                None
49            }
50            SchemaType::Float(inner) => inner.default.as_ref(),
51            SchemaType::Integer(inner) => inner.default.as_ref(),
52            SchemaType::String(inner) => inner.default.as_ref(),
53            SchemaType::Union(inner) => {
54                if let Some(index) = &inner.default_index {
55                    if let Some(value) = inner.variants_types.get(*index) {
56                        return value.get_default();
57                    }
58                }
59
60                for variant in &inner.variants_types {
61                    if let Some(value) = variant.get_default() {
62                        return Some(value);
63                    }
64                }
65
66                None
67            }
68            _ => None,
69        }
70    }
71
72    /// Return true if the schema is an explicit null.
73    pub fn is_null(&self) -> bool {
74        matches!(self, SchemaType::Null)
75    }
76
77    /// Return true if the schema is nullable (a union with a null).
78    pub fn is_nullable(&self) -> bool {
79        if let SchemaType::Union(uni) = self {
80            return uni.has_null();
81        }
82
83        false
84    }
85
86    /// Return true if the schema is a reference.
87    pub fn is_reference(&self) -> bool {
88        matches!(self, SchemaType::Reference(_))
89    }
90
91    /// Return true if the schema is a struct.
92    pub fn is_struct(&self) -> bool {
93        matches!(self, SchemaType::Struct(_))
94    }
95
96    /// Set the `default` of the inner schema type.
97    pub fn set_default(&mut self, default: LiteralValue) {
98        match self {
99            SchemaType::Boolean(inner) => {
100                inner.default = Some(default);
101            }
102            SchemaType::Float(inner) => {
103                inner.default = Some(default);
104            }
105            SchemaType::Integer(inner) => {
106                inner.default = Some(default);
107            }
108            SchemaType::String(inner) => {
109                inner.default = Some(default);
110            }
111            _ => {}
112        };
113    }
114
115    /// Add a field to the type if it's a struct.
116    pub fn add_field(&mut self, key: &str, value: impl Into<SchemaField>) {
117        if let SchemaType::Struct(map) = self {
118            map.fields.insert(key.to_owned(), Box::new(value.into()));
119        }
120    }
121}
122
123impl From<SchemaType> for Schema {
124    fn from(val: SchemaType) -> Self {
125        Schema::new(val)
126    }
127}
128
129impl Schematic for SchemaType {}