1use turso_orm_driver::FromValue;
19use turso_sql::{ColumnType, Value};
20
21pub trait TursoType: Sized + Clone + Send + Sync + Into<Value> + FromValue + 'static {
28 const COLUMN_TYPE: ColumnType;
30 const NULLABLE: bool = false;
32 const INTEGRAL: bool = false;
34}
35
36macro_rules! simple {
38 ($($t:ty => $ct:expr, $integral:literal);* $(;)?) => {$(
39 impl TursoType for $t {
40 const COLUMN_TYPE: ColumnType = $ct;
41 const INTEGRAL: bool = $integral;
42 }
43 )*};
44}
45
46simple! {
47 bool => ColumnType::Boolean, false;
48 i8 => ColumnType::Integer, true;
49 i16 => ColumnType::Integer, true;
50 i32 => ColumnType::Integer, true;
51 i64 => ColumnType::Integer, true;
52 u8 => ColumnType::Integer, true;
53 u16 => ColumnType::Integer, true;
54 u32 => ColumnType::Integer, true;
55 f32 => ColumnType::Real, false;
56 f64 => ColumnType::Real, false;
57 String => ColumnType::Text, false;
58 Vec<u8> => ColumnType::Blob, false;
59}
60
61#[cfg(feature = "with-chrono")]
62simple! {
63 chrono::NaiveDate => ColumnType::Date, false;
64 chrono::NaiveTime => ColumnType::Time, false;
65 chrono::NaiveDateTime => ColumnType::DateTime, false;
66 chrono::DateTime<chrono::Utc> => ColumnType::TimestampWithTimeZone, false;
67 chrono::DateTime<chrono::FixedOffset> => ColumnType::TimestampWithTimeZone, false;
68}
69
70#[cfg(feature = "with-uuid")]
71simple! {
72 uuid::Uuid => ColumnType::Uuid, false;
73}
74
75#[cfg(feature = "with-json")]
76simple! {
77 serde_json::Value => ColumnType::Json, false;
78}
79
80#[cfg(feature = "with-rust_decimal")]
81simple! {
82 rust_decimal::Decimal => ColumnType::Decimal, false;
83}
84
85impl<T: TursoType> TursoType for Option<T> {
86 const COLUMN_TYPE: ColumnType = T::COLUMN_TYPE;
87 const NULLABLE: bool = true;
88 const INTEGRAL: bool = T::INTEGRAL;
89}
90
91pub trait TryFromU64: Sized {
97 fn try_from_u64(n: u64) -> crate::Result<Self>;
104}
105
106macro_rules! try_from_u64 {
108 ($($t:ty),*) => {$(
109 impl TryFromU64 for $t {
110 fn try_from_u64(n: u64) -> crate::Result<Self> {
111 <$t>::try_from(n).map_err(|_| crate::DbErr::Type(format!("row id {n} does not fit in {}", stringify!($t))))
112 }
113 }
114 )*};
115}
116try_from_u64!(i8, i16, i32, i64, u8, u16, u32, u64);
117
118macro_rules! no_try_from_u64 {
120 ($($t:ty),*) => {$(
121 impl TryFromU64 for $t {
122 fn try_from_u64(_: u64) -> crate::Result<Self> {
123 Err(crate::DbErr::Type(format!("{} primary keys are not generated by the database", stringify!($t))))
124 }
125 }
126 )*};
127}
128no_try_from_u64!(String, Vec<u8>, bool, f32, f64);
129#[cfg(feature = "with-uuid")]
130no_try_from_u64!(uuid::Uuid);
131
132macro_rules! tuple_try_from_u64 {
135 ($(($($t:ident),+)),* $(,)?) => {$(
136 impl<$($t: TryFromU64),+> TryFromU64 for ($($t,)+) {
137 fn try_from_u64(_: u64) -> crate::Result<Self> {
138 Err(crate::DbErr::Type(
139 "composite primary keys are not generated by the database".into(),
140 ))
141 }
142 }
143 )*};
144}
145tuple_try_from_u64!(
146 (A, B),
147 (A, B, C),
148 (A, B, C, D),
149 (A, B, C, D, E),
150 (A, B, C, D, E, F)
151);
152
153pub trait IntoValueTuple {
158 fn into_value_tuple(self) -> Vec<Value>;
160}
161
162macro_rules! single_value_tuple {
164 ($($t:ty),*) => {$(
165 impl IntoValueTuple for $t {
166 fn into_value_tuple(self) -> Vec<Value> {
167 vec![self.into()]
168 }
169 }
170 )*};
171}
172single_value_tuple!(
173 bool,
174 i8,
175 i16,
176 i32,
177 i64,
178 u8,
179 u16,
180 u32,
181 f32,
182 f64,
183 String,
184 &str,
185 Vec<u8>,
186 Value
187);
188#[cfg(feature = "with-uuid")]
189single_value_tuple!(uuid::Uuid);
190#[cfg(feature = "with-chrono")]
191single_value_tuple!(
192 chrono::NaiveDate,
193 chrono::NaiveDateTime,
194 chrono::DateTime<chrono::Utc>
195);
196
197macro_rules! tuple_into_value_tuple {
199 ($(($($t:ident $i:tt),+)),* $(,)?) => {$(
200 impl<$($t: Into<Value>),+> IntoValueTuple for ($($t,)+) {
201 fn into_value_tuple(self) -> Vec<Value> {
202 vec![$(self.$i.into()),+]
203 }
204 }
205 )*};
206}
207tuple_into_value_tuple!(
208 (A 0, B 1),
209 (A 0, B 1, C 2),
210 (A 0, B 1, C 2, D 3),
211 (A 0, B 1, C 2, D 3, E 4),
212 (A 0, B 1, C 2, D 3, E 4, F 5),
213);