drizzle_core/traits/
column.rs

1use core::any::Any;
2
3use crate::expr::Expr;
4use crate::{SQLParam, SQLSchema, SQLSchemaType, SQLTable, SQLTableInfo};
5
6pub trait SQLColumnInfo: Any + Send + Sync {
7    fn is_not_null(&self) -> bool;
8    fn is_primary_key(&self) -> bool;
9    fn is_unique(&self) -> bool;
10    fn name(&self) -> &str;
11    fn r#type(&self) -> &str;
12    fn has_default(&self) -> bool;
13
14    fn table(&self) -> &dyn SQLTableInfo;
15    /// Returns the foreign key reference if this column has one.
16    fn foreign_key(&self) -> Option<&'static dyn SQLColumnInfo> {
17        None
18    }
19
20    /// Returns the foreign key table if this column references one.
21    fn foreign_key_table(&self) -> Option<&'static dyn SQLTableInfo> {
22        self.foreign_key().map(|fk| fk.table())
23    }
24
25    fn as_column(&self) -> &dyn SQLColumnInfo
26    where
27        Self: Sized,
28    {
29        self
30    }
31}
32
33/// Column trait tying expression lifetimes to parameter values via `'a`.
34pub trait SQLColumn<'a, Value: SQLParam + 'a>:
35    SQLColumnInfo + Default + SQLSchema<'a, &'a str, Value> + Expr<'a, Value>
36{
37    type Table: SQLTable<'a, Self::TableType, Value>;
38    type TableType: SQLSchemaType;
39    type Type: TryInto<Value>;
40
41    const PRIMARY_KEY: bool = false;
42    const NOT_NULL: bool = false;
43    const UNIQUE: bool = false;
44    const DEFAULT: Option<Self::Type> = None;
45
46    fn default_fn(&'a self) -> Option<impl Fn() -> Self::Type> {
47        None::<fn() -> Self::Type>
48    }
49}
50
51// Blanket implementation for static references
52impl<T: SQLColumnInfo> SQLColumnInfo for &'static T {
53    fn is_not_null(&self) -> bool {
54        (*self).is_not_null()
55    }
56
57    fn is_primary_key(&self) -> bool {
58        (*self).is_primary_key()
59    }
60
61    fn is_unique(&self) -> bool {
62        (*self).is_unique()
63    }
64
65    fn name(&self) -> &str {
66        (*self).name()
67    }
68
69    fn r#type(&self) -> &str {
70        (*self).r#type()
71    }
72
73    fn has_default(&self) -> bool {
74        (*self).has_default()
75    }
76
77    fn table(&self) -> &dyn SQLTableInfo {
78        (*self).table()
79    }
80
81    fn foreign_key(&self) -> Option<&'static dyn SQLColumnInfo> {
82        (*self).foreign_key()
83    }
84}
85
86impl core::fmt::Debug for dyn SQLColumnInfo {
87    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
88        f.debug_struct("SQLColumnInfo")
89            .field("name", &self.name())
90            .field("type", &self.r#type())
91            .field("not_null", &self.is_not_null())
92            .field("primary_key", &self.is_primary_key())
93            .field("unique", &self.is_unique())
94            .field("table", &self.table().name())
95            .field("has_default", &self.has_default())
96            .finish()
97    }
98}