use std::{
fmt::{
Debug,
Display,
},
rc::Rc,
ops::Deref,
};
use crate::{
sqlite::{
types::{
SimpleSimpleType,
SimpleType,
Type,
},
query::{
expr::{
Expr,
},
},
},
};
use super::table::{
Table,
};
#[derive(Clone, Debug)]
pub struct FieldType {
pub type_: Type,
pub migration_default: Option<Expr>,
}
impl FieldType {
pub fn with(t: &Type) -> Self {
Self {
type_: t.clone(),
migration_default: None,
}
}
pub fn with_migration(t: &Type, def: Option<Expr>) -> Self {
if t.opt {
panic!("Optional fields can't have defaults.");
}
Self {
type_: t.clone(),
migration_default: def,
}
}
}
pub struct FieldBuilder {
t: SimpleSimpleType,
default_: Option<Expr>,
opt: bool,
custom: Option<String>,
}
impl FieldBuilder {
fn new(t: SimpleSimpleType) -> FieldBuilder {
FieldBuilder {
t: t,
opt: false,
default_: None,
custom: None,
}
}
pub fn opt(mut self) -> FieldBuilder {
if self.default_.is_some() {
panic!("Optional fields can't have migration fill expressions.");
}
self.opt = true;
self
}
pub fn migrate_fill(mut self, expr: Expr) -> FieldBuilder {
if self.opt {
panic!("Optional fields can't have migration fill expressions.");
}
self.default_ = Some(expr);
self
}
pub fn custom(mut self, type_: impl ToString) -> FieldBuilder {
self.custom = Some(type_.to_string());
self
}
pub fn build(self) -> FieldType {
FieldType {
type_: Type {
type_: SimpleType {
custom: self.custom,
type_: self.t,
},
opt: self.opt,
},
migration_default: self.default_,
}
}
}
pub fn field_bool() -> FieldBuilder {
FieldBuilder::new(SimpleSimpleType::Bool)
}
pub fn field_i32() -> FieldBuilder {
FieldBuilder::new(SimpleSimpleType::I32)
}
pub fn field_i64() -> FieldBuilder {
FieldBuilder::new(SimpleSimpleType::I64)
}
pub fn field_u32() -> FieldBuilder {
FieldBuilder::new(SimpleSimpleType::U32)
}
pub fn field_f32() -> FieldBuilder {
FieldBuilder::new(SimpleSimpleType::F32)
}
pub fn field_f64() -> FieldBuilder {
FieldBuilder::new(SimpleSimpleType::F64)
}
pub fn field_str() -> FieldBuilder {
FieldBuilder::new(SimpleSimpleType::String)
}
pub fn field_bytes() -> FieldBuilder {
FieldBuilder::new(SimpleSimpleType::Bytes)
}
#[cfg(feature = "chrono")]
pub fn field_utctime_s() -> FieldBuilder {
FieldBuilder::new(SimpleSimpleType::UtcTimeS)
}
#[cfg(feature = "chrono")]
pub fn field_utctime_ms() -> FieldBuilder {
FieldBuilder::new(SimpleSimpleType::UtcTimeMs)
}
#[cfg(feature = "chrono")]
pub fn field_fixed_offset_time_ms() -> FieldBuilder {
FieldBuilder::new(SimpleSimpleType::FixedOffsetTimeMs)
}
#[derive(Clone, Eq, PartialEq, Hash, Debug, PartialOrd, Ord)]
pub struct SchemaFieldId(pub String);
impl Display for SchemaFieldId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Display::fmt(&self.0, f)
}
}
#[derive(Debug)]
pub struct Field_ {
pub table: Table,
pub schema_id: SchemaFieldId,
pub id: String,
pub type_: FieldType,
}
#[derive(Clone, Debug)]
pub struct Field(pub Rc<Field_>);
impl std::hash::Hash for Field {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.0.schema_id.hash(state)
}
}
impl PartialEq for Field {
fn eq(&self, other: &Self) -> bool {
self.table == other.table && self.schema_id == other.schema_id
}
}
impl Eq for Field { }
impl Deref for Field {
type Target = Field_;
fn deref(&self) -> &Self::Target {
self.0.as_ref()
}
}
impl Display for Field {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Display::fmt(&format!("{}.{} ({}.{})", self.table.id, self.id, self.table.schema_id.0, self.schema_id.0), f)
}
}