use std::fmt;
use serde::{Deserialize, Serialize};
use super::column_type::ColumnType;
#[derive(
Debug,
Clone,
PartialEq,
Eq,
Hash,
Serialize,
Deserialize,
zerompk::ToMessagePack,
zerompk::FromMessagePack,
)]
#[msgpack(c_enum)]
#[repr(u8)]
pub enum ColumnModifier {
TimeKey = 0,
SpatialIndex = 1,
}
#[non_exhaustive]
#[derive(
Debug,
Clone,
PartialEq,
Eq,
Serialize,
Deserialize,
zerompk::ToMessagePack,
zerompk::FromMessagePack,
)]
pub struct ColumnDef {
pub name: String,
pub column_type: ColumnType,
pub nullable: bool,
pub default: Option<String>,
pub primary_key: bool,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub modifiers: Vec<ColumnModifier>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub generated_expr: Option<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub generated_deps: Vec<String>,
#[serde(default = "default_added_at_version")]
pub added_at_version: u32,
}
fn default_added_at_version() -> u32 {
1
}
impl ColumnDef {
pub fn required(name: impl Into<String>, column_type: ColumnType) -> Self {
Self {
name: name.into(),
column_type,
nullable: false,
default: None,
primary_key: false,
modifiers: Vec::new(),
generated_expr: None,
generated_deps: Vec::new(),
added_at_version: 1,
}
}
pub fn nullable(name: impl Into<String>, column_type: ColumnType) -> Self {
Self {
name: name.into(),
column_type,
nullable: true,
default: None,
primary_key: false,
modifiers: Vec::new(),
generated_expr: None,
generated_deps: Vec::new(),
added_at_version: 1,
}
}
pub fn with_primary_key(mut self) -> Self {
self.primary_key = true;
self.nullable = false;
self
}
pub fn is_time_key(&self) -> bool {
self.modifiers.contains(&ColumnModifier::TimeKey)
}
pub fn is_spatial_index(&self) -> bool {
self.modifiers.contains(&ColumnModifier::SpatialIndex)
}
pub fn with_default(mut self, expr: impl Into<String>) -> Self {
self.default = Some(expr.into());
self
}
}
impl fmt::Display for ColumnDef {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} {}", self.name, self.column_type)?;
if !self.nullable {
write!(f, " NOT NULL")?;
}
if self.primary_key {
write!(f, " PRIMARY KEY")?;
}
if let Some(ref d) = self.default {
write!(f, " DEFAULT {d}")?;
}
Ok(())
}
}