use crate::Schematic;
use crate::arrays::*;
use crate::bools::*;
use crate::enums::*;
use crate::literals::*;
use crate::numbers::*;
use crate::objects::*;
use crate::schema::*;
use crate::strings::*;
use crate::structs::*;
use crate::tuples::*;
use crate::unions::*;
use std::fmt;
#[derive(Clone, Debug, Default, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(feature = "serde", serde(tag = "type"))]
pub enum SchemaType {
Null,
#[default]
Unknown,
Array(Box<ArrayType>),
Boolean(Box<BooleanType>),
Enum(Box<EnumType>),
Float(Box<FloatType>),
Integer(Box<IntegerType>),
Literal(Box<LiteralType>),
Object(Box<ObjectType>),
Reference(String),
Struct(Box<StructType>),
String(Box<StringType>),
Tuple(Box<TupleType>),
Union(Box<UnionType>),
}
impl SchemaType {
pub fn get_default(&self) -> Option<&LiteralValue> {
match self {
SchemaType::Boolean(inner) => inner.default.as_ref(),
SchemaType::Enum(inner) => {
if let Some(index) = &inner.default_index
&& let Some(value) = inner.values.get(*index)
{
return Some(value);
}
None
}
SchemaType::Float(inner) => inner.default.as_ref(),
SchemaType::Integer(inner) => inner.default.as_ref(),
SchemaType::String(inner) => inner.default.as_ref(),
SchemaType::Union(inner) => {
if let Some(index) = &inner.default_index
&& let Some(value) = inner.variants_types.get(*index)
{
return value.get_default();
}
for variant in &inner.variants_types {
if let Some(value) = variant.get_default() {
return Some(value);
}
}
None
}
_ => None,
}
}
pub fn is_null(&self) -> bool {
matches!(self, SchemaType::Null)
}
pub fn is_nullable(&self) -> bool {
if let SchemaType::Union(uni) = self {
return uni.has_null();
}
false
}
pub fn is_reference(&self) -> bool {
matches!(self, SchemaType::Reference(_))
}
pub fn is_struct(&self) -> bool {
matches!(self, SchemaType::Struct(_))
}
pub fn set_default(&mut self, default: LiteralValue) {
match self {
SchemaType::Boolean(inner) => {
inner.default = Some(default);
}
SchemaType::Float(inner) => {
inner.default = Some(default);
}
SchemaType::Integer(inner) => {
inner.default = Some(default);
}
SchemaType::String(inner) => {
inner.default = Some(default);
}
_ => {}
};
}
pub fn add_field(&mut self, key: &str, value: impl Into<SchemaField>) {
if let SchemaType::Struct(map) = self {
map.fields.insert(key.to_owned(), Box::new(value.into()));
}
}
}
impl From<SchemaType> for Schema {
fn from(val: SchemaType) -> Self {
Schema::new(val)
}
}
impl Schematic for SchemaType {}
impl fmt::Display for SchemaType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{}",
match self {
Self::Null => "null".to_string(),
Self::Unknown => "unknown".to_string(),
Self::Array(inner) => inner.to_string(),
Self::Boolean(inner) => inner.to_string(),
Self::Enum(inner) => inner.to_string(),
Self::Float(inner) => inner.to_string(),
Self::Integer(inner) => inner.to_string(),
Self::Literal(inner) => inner.to_string(),
Self::Object(inner) => inner.to_string(),
Self::Reference(inner) => inner.to_string(),
Self::Struct(inner) => inner.to_string(),
Self::String(inner) => inner.to_string(),
Self::Tuple(inner) => inner.to_string(),
Self::Union(inner) => inner.to_string(),
}
)
}
}