#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum TypeSchema {
Unit,
Bool,
I8,
I16,
I32,
I64,
I128,
Isize,
U8,
U16,
U32,
U64,
U128,
Usize,
F32,
F64,
Char,
Str,
Bytes,
Opaque,
Seq(&'static TypeSchema),
Map(&'static TypeSchema),
Optional(&'static TypeSchema),
Tuple(&'static [TypeSchema]),
Struct(&'static StructSchema),
Enum(&'static EnumSchema),
}
impl TypeSchema {
pub fn name(&self) -> &'static str {
match self {
TypeSchema::Unit => "unit",
TypeSchema::Bool => "bool",
TypeSchema::I8 => "i8",
TypeSchema::I16 => "i16",
TypeSchema::I32 => "i32",
TypeSchema::I64 => "i64",
TypeSchema::I128 => "i128",
TypeSchema::Isize => "isize",
TypeSchema::U8 => "u8",
TypeSchema::U16 => "u16",
TypeSchema::U32 => "u32",
TypeSchema::U64 => "u64",
TypeSchema::U128 => "u128",
TypeSchema::Usize => "usize",
TypeSchema::F32 => "f32",
TypeSchema::F64 => "f64",
TypeSchema::Char => "char",
TypeSchema::Str => "string",
TypeSchema::Bytes => "bytes",
TypeSchema::Opaque => "opaque",
TypeSchema::Seq(_) => "sequence",
TypeSchema::Map(_) => "map",
TypeSchema::Optional(inner) => inner.name(),
TypeSchema::Tuple(_) => "tuple",
TypeSchema::Struct(s) => s.name,
TypeSchema::Enum(e) => e.name,
}
}
pub fn is_object(&self) -> bool {
matches!(self, TypeSchema::Struct(_) | TypeSchema::Map(_))
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct StructSchema {
pub name: &'static str,
pub transparent: bool,
pub fields: &'static [FieldSchema],
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct FieldSchema {
pub name: &'static str,
pub orig: &'static str,
pub required: bool,
pub flattened: bool,
pub ty: TypeSchema,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct EnumSchema {
pub name: &'static str,
pub tag: Option<&'static str>,
pub content: Option<&'static str>,
pub untagged: bool,
pub default_tag: &'static str,
pub variants: &'static [VariantSchema],
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct VariantSchema {
pub name: &'static str,
pub orig: &'static str,
pub ty: TypeSchema,
}
pub trait NsonSchema {
const SCHEMA: TypeSchema;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn schema_is_const_constructible() {
const S: TypeSchema = TypeSchema::Struct(&StructSchema {
name: "Foo",
transparent: false,
fields: &[FieldSchema {
name: "x",
orig: "x",
required: true,
flattened: false,
ty: TypeSchema::F64,
}],
});
assert_eq!(S.name(), "Foo");
assert!(S.is_object());
}
#[test]
fn optional_name_unwraps() {
assert_eq!(TypeSchema::Optional(&TypeSchema::I32).name(), "i32");
}
}