use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum PrimitiveType {
Boolean,
Int,
Long,
Float,
Double,
Decimal {
precision: u32,
scale: u32,
},
Date,
Time,
Timestamp,
Timestamptz,
String,
Uuid,
Fixed(u64),
Binary,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum Type {
Primitive(PrimitiveType),
Struct(StructType),
List(ListType),
Map(MapType),
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct StructType {
#[serde(rename = "type")]
r#type: String,
#[serde(rename = "fields")]
fields: Vec<NestedField>,
}
impl StructType {
pub fn new(fields: Vec<NestedField>) -> Self {
Self {
r#type: "struct".to_string(),
fields,
}
}
pub fn fields(&self) -> &[NestedField] {
&self.fields
}
pub fn field_by_name(&self, name: &str) -> Option<&NestedField> {
self.fields.iter().find(|f| f.name() == name)
}
pub fn field_by_id(&self, id: i32) -> Option<&NestedField> {
self.fields.iter().find(|f| f.id() == id)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ListType {
element_id: i32,
element_required: bool,
element_type: Box<Type>,
}
impl ListType {
pub fn new(element_id: i32, element_required: bool, element_type: Type) -> Self {
Self {
element_id,
element_required,
element_type: Box::new(element_type),
}
}
pub fn element_type(&self) -> &Type {
&self.element_type
}
pub fn element_required(&self) -> bool {
self.element_required
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct MapType {
key_id: i32,
key_type: Box<Type>,
value_id: i32,
value_required: bool,
value_type: Box<Type>,
}
impl MapType {
pub fn new(
key_id: i32,
key_type: Type,
value_id: i32,
value_required: bool,
value_type: Type,
) -> Self {
Self {
key_id,
key_type: Box::new(key_type),
value_id,
value_required,
value_type: Box::new(value_type),
}
}
pub fn key_type(&self) -> &Type {
&self.key_type
}
pub fn value_type(&self) -> &Type {
&self.value_type
}
pub fn value_required(&self) -> bool {
self.value_required
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct NestedField {
id: i32,
name: String,
required: bool,
#[serde(rename = "type")]
field_type: Type,
#[serde(skip_serializing_if = "Option::is_none")]
doc: Option<String>,
}
impl NestedField {
pub fn new(
id: i32,
name: String,
field_type: Type,
required: bool,
doc: Option<String>,
) -> Self {
Self {
id,
name,
required,
field_type,
doc,
}
}
pub fn required_field(id: i32, name: String, field_type: Type) -> Self {
Self::new(id, name, field_type, true, None)
}
pub fn optional_field(id: i32, name: String, field_type: Type) -> Self {
Self::new(id, name, field_type, false, None)
}
pub fn id(&self) -> i32 {
self.id
}
pub fn name(&self) -> &str {
&self.name
}
pub fn is_required(&self) -> bool {
self.required
}
pub fn field_type(&self) -> &Type {
&self.field_type
}
pub fn doc(&self) -> Option<&str> {
self.doc.as_deref()
}
}