use core::fmt;
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct SchemaId(pub u64);
impl fmt::Debug for SchemaId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "SchemaId({:#018x})", self.0)
}
}
impl fmt::Display for SchemaId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:016x}", self.0)
}
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Schema {
pub id: SchemaId,
pub type_params: Vec<String>,
pub kind: SchemaKind,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum SchemaKind {
Primitive(Primitive),
Struct {
name: String,
fields: Vec<Field>,
},
Enum {
name: String,
variants: Vec<Variant>,
},
Tuple {
elements: Vec<SchemaRef>,
},
List {
element: SchemaRef,
},
Set {
element: SchemaRef,
},
Map {
key: SchemaRef,
value: SchemaRef,
},
Array {
element: SchemaRef,
dimensions: Vec<u64>,
},
Tensor {
element: SchemaRef,
rank: Option<u32>,
},
Option {
element: SchemaRef,
},
Channel {
direction: ChannelDirection,
element: SchemaRef,
},
Dynamic,
External {
kind: String,
metadata: Option<SchemaRef>,
},
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum ChannelDirection {
Tx,
Rx,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum SchemaRef {
Concrete { id: SchemaId, args: Vec<SchemaRef> },
Var { name: String },
}
impl SchemaRef {
#[must_use]
pub fn concrete(id: SchemaId) -> Self {
SchemaRef::Concrete {
id,
args: Vec::new(),
}
}
#[must_use]
pub fn generic(id: SchemaId, args: Vec<SchemaRef>) -> Self {
SchemaRef::Concrete { id, args }
}
#[must_use]
pub fn var(name: impl Into<String>) -> Self {
SchemaRef::Var { name: name.into() }
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum Primitive {
Bool,
U8,
U16,
U32,
U64,
U128,
I8,
I16,
I32,
I64,
I128,
F32,
F64,
Char,
String,
Bytes,
DateTime,
Uuid,
QName,
Unit,
Never,
}
impl Primitive {
pub const ALL: [Primitive; 21] = [
Primitive::Bool,
Primitive::U8,
Primitive::U16,
Primitive::U32,
Primitive::U64,
Primitive::U128,
Primitive::I8,
Primitive::I16,
Primitive::I32,
Primitive::I64,
Primitive::I128,
Primitive::F32,
Primitive::F64,
Primitive::Char,
Primitive::String,
Primitive::Bytes,
Primitive::DateTime,
Primitive::Uuid,
Primitive::QName,
Primitive::Unit,
Primitive::Never,
];
#[must_use]
pub fn tag(self) -> &'static str {
match self {
Primitive::Bool => "bool",
Primitive::U8 => "u8",
Primitive::U16 => "u16",
Primitive::U32 => "u32",
Primitive::U64 => "u64",
Primitive::U128 => "u128",
Primitive::I8 => "i8",
Primitive::I16 => "i16",
Primitive::I32 => "i32",
Primitive::I64 => "i64",
Primitive::I128 => "i128",
Primitive::F32 => "f32",
Primitive::F64 => "f64",
Primitive::Char => "char",
Primitive::String => "string",
Primitive::Bytes => "bytes",
Primitive::DateTime => "datetime",
Primitive::Uuid => "uuid",
Primitive::QName => "qname",
Primitive::Unit => "unit",
Primitive::Never => "never",
}
}
#[must_use]
pub fn from_tag(tag: &str) -> Option<Primitive> {
Some(match tag {
"bool" => Primitive::Bool,
"u8" => Primitive::U8,
"u16" => Primitive::U16,
"u32" => Primitive::U32,
"u64" => Primitive::U64,
"u128" => Primitive::U128,
"i8" => Primitive::I8,
"i16" => Primitive::I16,
"i32" => Primitive::I32,
"i64" => Primitive::I64,
"i128" => Primitive::I128,
"f32" => Primitive::F32,
"f64" => Primitive::F64,
"char" => Primitive::Char,
"string" => Primitive::String,
"bytes" => Primitive::Bytes,
"datetime" => Primitive::DateTime,
"uuid" => Primitive::Uuid,
"qname" => Primitive::QName,
"unit" => Primitive::Unit,
"never" => Primitive::Never,
_ => return None,
})
}
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Field {
pub name: String,
pub schema: SchemaRef,
pub required: bool,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Variant {
pub name: String,
pub index: u32,
pub payload: VariantPayload,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum VariantPayload {
Unit,
Newtype(SchemaRef),
Tuple(Vec<SchemaRef>),
Struct(Vec<Field>),
}