vespertide_core/schema/
column.rs

1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3
4use crate::schema::{foreign_key::ForeignKeyDef, names::ColumnName, str_or_bool::StrOrBoolOrArray};
5
6#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
7#[serde(rename_all = "snake_case")]
8pub struct ColumnDef {
9    pub name: ColumnName,
10    pub r#type: ColumnType,
11    pub nullable: bool,
12    pub default: Option<String>,
13    pub comment: Option<String>,
14    pub primary_key: Option<bool>,
15    pub unique: Option<StrOrBoolOrArray>,
16    pub index: Option<StrOrBoolOrArray>,
17    pub foreign_key: Option<ForeignKeyDef>,
18}
19
20#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
21#[serde(rename_all = "snake_case", untagged)]
22pub enum ColumnType {
23    Simple(SimpleColumnType),
24    Complex(ComplexColumnType),
25}
26
27impl ColumnType {
28    /// Convert column type to PostgreSQL SQL type string
29    pub fn to_sql(&self) -> String {
30        match self {
31            ColumnType::Simple(ty) => match ty {
32                SimpleColumnType::SmallInt => "SMALLINT".into(),
33                SimpleColumnType::Integer => "INTEGER".into(),
34                SimpleColumnType::BigInt => "BIGINT".into(),
35                SimpleColumnType::Real => "REAL".into(),
36                SimpleColumnType::DoublePrecision => "DOUBLE PRECISION".into(),
37                SimpleColumnType::Text => "TEXT".into(),
38                SimpleColumnType::Boolean => "BOOLEAN".into(),
39                SimpleColumnType::Date => "DATE".into(),
40                SimpleColumnType::Time => "TIME".into(),
41                SimpleColumnType::Timestamp => "TIMESTAMP".into(),
42                SimpleColumnType::Timestamptz => "TIMESTAMPTZ".into(),
43                SimpleColumnType::Bytea => "BYTEA".into(),
44                SimpleColumnType::Uuid => "UUID".into(),
45                SimpleColumnType::Json => "JSON".into(),
46                SimpleColumnType::Jsonb => "JSONB".into(),
47                SimpleColumnType::Inet => "INET".into(),
48                SimpleColumnType::Cidr => "CIDR".into(),
49                SimpleColumnType::Macaddr => "MACADDR".into(),
50            },
51            ColumnType::Complex(ty) => match ty {
52                ComplexColumnType::Varchar { length } => format!("VARCHAR({})", length),
53                ComplexColumnType::Custom { custom_type } => custom_type.clone(),
54            },
55        }
56    }
57
58    /// Convert column type to Rust type string (for SeaORM entity generation)
59    pub fn to_rust_type(&self, nullable: bool) -> String {
60        let base = match self {
61            ColumnType::Simple(ty) => match ty {
62                SimpleColumnType::SmallInt => "i16".to_string(),
63                SimpleColumnType::Integer => "i32".to_string(),
64                SimpleColumnType::BigInt => "i64".to_string(),
65                SimpleColumnType::Real => "f32".to_string(),
66                SimpleColumnType::DoublePrecision => "f64".to_string(),
67                SimpleColumnType::Text => "String".to_string(),
68                SimpleColumnType::Boolean => "bool".to_string(),
69                SimpleColumnType::Date => "Date".to_string(),
70                SimpleColumnType::Time => "Time".to_string(),
71                SimpleColumnType::Timestamp => "DateTime".to_string(),
72                SimpleColumnType::Timestamptz => "DateTimeWithTimeZone".to_string(),
73                SimpleColumnType::Bytea => "Vec<u8>".to_string(),
74                SimpleColumnType::Uuid => "Uuid".to_string(),
75                SimpleColumnType::Json | SimpleColumnType::Jsonb => "Json".to_string(),
76                SimpleColumnType::Inet | SimpleColumnType::Cidr => "String".to_string(),
77                SimpleColumnType::Macaddr => "String".to_string(),
78            },
79            ColumnType::Complex(ty) => match ty {
80                ComplexColumnType::Varchar { .. } => "String".to_string(),
81                ComplexColumnType::Custom { .. } => "String".to_string(), // Default for custom types
82            },
83        };
84
85        if nullable {
86            format!("Option<{}>", base)
87        } else {
88            base
89        }
90    }
91}
92
93#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
94#[serde(rename_all = "snake_case")]
95pub enum SimpleColumnType {
96    SmallInt,
97    Integer,
98    BigInt,
99    Real,
100    DoublePrecision,
101
102    // Text types
103    Text,
104
105    // Boolean type
106    Boolean,
107
108    // Date/Time types
109    Date,
110    Time,
111    Timestamp,
112    Timestamptz,
113
114    // Binary type
115    Bytea,
116
117    // UUID type
118    Uuid,
119
120    // JSON types
121    Json,
122    Jsonb,
123
124    // Network types
125    Inet,
126    Cidr,
127    Macaddr,
128}
129
130#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
131#[serde(rename_all = "snake_case", tag = "kind")]
132pub enum ComplexColumnType {
133    Varchar { length: u32 },
134    Custom { custom_type: String },
135}
136
137impl From<SimpleColumnType> for ColumnType {
138    fn from(ty: SimpleColumnType) -> Self {
139        ColumnType::Simple(ty)
140    }
141}
142
143impl From<ComplexColumnType> for ColumnType {
144    fn from(ty: ComplexColumnType) -> Self {
145        ColumnType::Complex(ty)
146    }
147}