mod canonical_form;
mod check_for_cycles;
mod parsing;
mod rabin;
mod serialize;
use super::{Fixed, Name, SchemaError};
pub use check_for_cycles::UnconditionalCycle;
#[derive(Clone, Debug)]
pub struct SchemaMut {
pub(super) nodes: Vec<SchemaNode>,
pub(super) schema_json: Option<String>,
}
impl SchemaMut {
pub fn nodes(&self) -> &[SchemaNode] {
&self.nodes
}
pub fn nodes_mut(&mut self) -> &mut Vec<SchemaNode> {
self.schema_json = None;
&mut self.nodes
}
pub fn root(&self) -> &SchemaNode {
self.nodes.first().expect(
"Schema should have nodes - have you updated it \
in such a way that all of its nodes were removed?",
)
}
pub fn from_nodes(nodes: Vec<SchemaNode>) -> Self {
Self {
nodes,
schema_json: None,
}
}
pub fn freeze(self) -> Result<super::Schema, SchemaError> {
self.try_into()
}
pub fn get(&self, key: SchemaKey) -> Option<&SchemaNode> {
self.nodes.get(key.idx)
}
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct SchemaKey {
pub(super) idx: usize,
}
impl SchemaKey {
pub const fn from_idx(idx: usize) -> Self {
Self { idx }
}
pub const fn idx(self) -> usize {
self.idx
}
pub const fn root() -> Self {
Self { idx: 0 }
}
}
impl std::ops::Index<SchemaKey> for SchemaMut {
type Output = SchemaNode;
fn index(&self, key: SchemaKey) -> &Self::Output {
&self.nodes[key.idx]
}
}
impl std::fmt::Debug for SchemaKey {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Debug::fmt(&self.idx, f)
}
}
#[derive(Clone, Debug)]
pub enum SchemaNode {
RegularType(RegularType),
LogicalType {
inner: SchemaKey,
logical_type: LogicalType,
},
}
#[derive(Clone, Debug)]
pub enum RegularType {
Null,
Boolean,
Int,
Long,
Float,
Double,
Bytes,
String,
Array(Array),
Map(Map),
Union(Union),
Record(Record),
Enum(Enum),
Fixed(Fixed),
}
#[derive(Clone, Debug)]
pub struct Array {
pub items: SchemaKey,
pub(crate) _private: (),
}
impl Array {
pub fn new(items: SchemaKey) -> Self {
Self {
items,
_private: (),
}
}
}
#[derive(Clone, Debug)]
pub struct Map {
pub values: SchemaKey,
pub(crate) _private: (),
}
impl Map {
pub fn new(values: SchemaKey) -> Self {
Self {
values,
_private: (),
}
}
}
#[derive(Clone, Debug)]
pub struct Union {
pub variants: Vec<SchemaKey>,
pub(crate) _private: (),
}
impl Union {
pub fn new(variants: Vec<SchemaKey>) -> Self {
Self {
variants,
_private: (),
}
}
}
#[derive(Clone, Debug)]
pub struct Record {
pub fields: Vec<RecordField>,
pub name: Name,
pub(crate) _private: (),
}
impl Record {
pub fn new(name: Name, fields: Vec<RecordField>) -> Self {
Self {
fields,
name,
_private: (),
}
}
}
#[derive(Clone, Debug)]
pub struct RecordField {
pub name: String,
pub type_: SchemaKey,
pub(crate) _private: (),
}
impl RecordField {
pub fn new(name: impl Into<String>, schema: SchemaKey) -> Self {
Self {
name: name.into(),
type_: schema,
_private: (),
}
}
}
#[derive(Clone, Debug)]
pub struct Enum {
pub symbols: Vec<String>,
pub name: Name,
pub(crate) _private: (),
}
impl Enum {
pub fn new(name: Name, symbols: Vec<String>) -> Self {
Self {
symbols,
name,
_private: (),
}
}
}
#[derive(Clone, Debug)]
#[non_exhaustive]
pub enum LogicalType {
Decimal(Decimal),
Uuid,
Date,
TimeMillis,
TimeMicros,
TimestampMillis,
TimestampMicros,
Duration,
Unknown(UnknownLogicalType),
}
#[derive(Clone, Debug)]
pub struct Decimal {
pub scale: u32,
pub precision: usize,
pub(crate) _private: (),
}
impl Decimal {
pub fn new(scale: u32, precision: usize) -> Self {
Self {
precision,
scale,
_private: (),
}
}
}
#[derive(Clone, Debug)]
pub struct UnknownLogicalType {
pub logical_type_name: String,
_private: (),
}
impl UnknownLogicalType {
pub fn new(logical_type_name: impl Into<String>) -> Self {
Self {
logical_type_name: logical_type_name.into(),
_private: (),
}
}
pub fn as_str(&self) -> &str {
&self.logical_type_name
}
}
impl LogicalType {
pub fn as_str(&self) -> &str {
match self {
LogicalType::Decimal(_) => "decimal",
LogicalType::Uuid => "uuid",
LogicalType::Date => "date",
LogicalType::TimeMillis => "time-millis",
LogicalType::TimeMicros => "time-micros",
LogicalType::TimestampMillis => "timestamp-millis",
LogicalType::TimestampMicros => "timestamp-micros",
LogicalType::Duration => "duration",
LogicalType::Unknown(unknown_logical_type) => &unknown_logical_type.logical_type_name,
}
}
}
impl From<RegularType> for SchemaNode {
fn from(regular_type: RegularType) -> Self {
Self::RegularType(regular_type)
}
}
macro_rules! impl_froms_for_regular_type {
($($variant: ident)*) => {
$(
impl From<$variant> for RegularType {
fn from(variant: $variant) -> Self {
Self::$variant(variant)
}
}
impl From<$variant> for SchemaNode {
fn from(variant: $variant) -> Self {
SchemaNode::RegularType(RegularType::$variant(variant))
}
}
)*
};
}
impl_froms_for_regular_type! { Array Map Union Record Enum Fixed }