drizzle_core/
conversions.rs

1use crate::{
2    sql::SQL,
3    traits::{SQLColumnInfo, SQLParam, SQLTableInfo},
4};
5use std::borrow::Cow;
6
7#[cfg(feature = "uuid")]
8use uuid::Uuid;
9
10pub trait ToSQL<'a, V: SQLParam> {
11    fn to_sql(&self) -> SQL<'a, V>;
12}
13
14impl<'a, T, V> From<&T> for SQL<'a, V>
15where
16    T: ToSQL<'a, V>,
17    V: SQLParam,
18{
19    fn from(value: &T) -> Self {
20        value.to_sql()
21    }
22}
23
24impl<'a, V: SQLParam, T> ToSQL<'a, V> for &T
25where
26    T: ToSQL<'a, V>,
27{
28    fn to_sql(&self) -> SQL<'a, V> {
29        (**self).to_sql()
30    }
31}
32
33impl<'a, V: SQLParam + 'a> ToSQL<'a, V> for () {
34    fn to_sql(&self) -> SQL<'a, V> {
35        SQL::empty()
36    }
37}
38
39impl<'a, V, T> ToSQL<'a, V> for Vec<T>
40where
41    V: SQLParam + 'a,
42    T: ToSQL<'a, V>,
43{
44    fn to_sql(&self) -> SQL<'a, V> {
45        SQL::join(self.iter().map(ToSQL::to_sql), ", ")
46    }
47}
48
49impl<'a, V, T> ToSQL<'a, V> for &'a [T]
50where
51    V: SQLParam + 'a,
52    T: ToSQL<'a, V>,
53{
54    fn to_sql(&self) -> SQL<'a, V> {
55        SQL::join(self.iter().map(ToSQL::to_sql), ", ")
56    }
57}
58
59impl<'a, V, T, const N: usize> ToSQL<'a, V> for [T; N]
60where
61    V: SQLParam + 'a,
62    T: ToSQL<'a, V>,
63{
64    fn to_sql(&self) -> SQL<'a, V> {
65        SQL::join(self.iter().map(ToSQL::to_sql), ", ")
66    }
67}
68
69// Implement ToSQL for SQLTableInfo and SQLColumnInfo trait objects
70impl<'a, V: SQLParam + 'a> ToSQL<'a, V> for &'static dyn SQLTableInfo {
71    fn to_sql(&self) -> SQL<'a, V> {
72        SQL::table(*self)
73    }
74}
75
76impl<'a, V: SQLParam + 'a> ToSQL<'a, V> for &'static dyn SQLColumnInfo {
77    fn to_sql(&self) -> SQL<'a, V> {
78        SQL::column(*self)
79    }
80}
81
82impl<'a, V: SQLParam + 'a> ToSQL<'a, V> for Box<[&'static dyn SQLColumnInfo]> {
83    fn to_sql(&self) -> SQL<'a, V> {
84        SQL::join(self.iter().map(|&v| SQL::column(v)), ", ")
85    }
86}
87
88impl<'a, V: SQLParam + 'a> ToSQL<'a, V> for Box<[&'static dyn SQLTableInfo]> {
89    fn to_sql(&self) -> SQL<'a, V> {
90        SQL::join(self.iter().map(|&v| SQL::table(v)), ", ")
91    }
92}
93
94// Implement ToSQL for primitive types
95impl<'a, V> ToSQL<'a, V> for &'a str
96where
97    V: SQLParam + 'a,
98    V: From<&'a str>,
99    V: Into<Cow<'a, V>>,
100{
101    fn to_sql(&self) -> SQL<'a, V> {
102        SQL::parameter(V::from(self))
103    }
104}
105
106impl<'a, V> ToSQL<'a, V> for String
107where
108    V: SQLParam + 'a,
109    V: From<String>,
110    V: Into<Cow<'a, V>>,
111{
112    fn to_sql(&self) -> SQL<'a, V> {
113        SQL::parameter(V::from(self.clone()))
114    }
115}
116
117impl<'a, V> ToSQL<'a, V> for i32
118where
119    V: SQLParam + 'a + From<i64>,
120    V: Into<Cow<'a, V>>,
121{
122    fn to_sql(&self) -> SQL<'a, V> {
123        SQL::parameter(V::from(*self as i64))
124    }
125}
126
127impl<'a, V> ToSQL<'a, V> for i64
128where
129    V: SQLParam + 'a + From<i64>,
130    V: Into<Cow<'a, V>>,
131{
132    fn to_sql(&self) -> SQL<'a, V> {
133        SQL::parameter(V::from(*self))
134    }
135}
136
137impl<'a, V> ToSQL<'a, V> for f64
138where
139    V: SQLParam + 'a + From<f64>,
140    V: Into<Cow<'a, V>>,
141{
142    fn to_sql(&self) -> SQL<'a, V> {
143        SQL::parameter(V::from(*self))
144    }
145}
146
147impl<'a, V> ToSQL<'a, V> for bool
148where
149    V: SQLParam + 'a + From<i64>,
150    V: Into<Cow<'a, V>>,
151{
152    fn to_sql(&self) -> SQL<'a, V> {
153        SQL::parameter(V::from(*self as i64))
154    }
155}
156
157impl<'a, V, T> ToSQL<'a, V> for Option<T>
158where
159    V: SQLParam + 'a,
160    T: ToSQL<'a, V>,
161{
162    fn to_sql(&self) -> SQL<'a, V> {
163        match self {
164            Some(value) => value.to_sql(), // Let the inner type handle parameterization
165            None => SQL::raw("NULL"),      // NULL is a keyword, use raw
166        }
167    }
168}
169
170#[cfg(feature = "uuid")]
171impl<'a, V> ToSQL<'a, V> for Uuid
172where
173    V: SQLParam + 'a,
174    V: From<Uuid>,
175    V: Into<Cow<'a, V>>,
176{
177    fn to_sql(&self) -> SQL<'a, V> {
178        SQL::parameter(V::from(*self))
179    }
180}