diesel/type_impls/
primitives.rs

1use std::error::Error;
2use std::io::Write;
3
4use crate::backend::Backend;
5use crate::deserialize::{self, FromSql, Queryable};
6use crate::query_builder::bind_collector::RawBytesBindCollector;
7use crate::serialize::{self, IsNull, Output, ToSql};
8use crate::sql_types::{
9    self, BigInt, Binary, Bool, Double, Float, Integer, SingleValue, SmallInt, Text,
10};
11use std::borrow::Cow;
12use std::fmt;
13
14#[allow(dead_code)]
15mod foreign_impls {
16    use super::*;
17    use crate::deserialize::FromSqlRow;
18
19    #[derive(AsExpression, FromSqlRow)]
20    #[diesel(foreign_derive)]
21    #[diesel(sql_type = Bool)]
22    struct BoolProxy(bool);
23
24    #[derive(FromSqlRow)]
25    #[cfg_attr(feature = "mysql_backend", derive(AsExpression))]
26    #[diesel(foreign_derive)]
27    #[cfg_attr(feature = "mysql_backend", diesel(sql_type = crate::sql_types::TinyInt))]
28    struct I8Proxy(i8);
29
30    #[derive(AsExpression, FromSqlRow)]
31    #[diesel(foreign_derive)]
32    #[diesel(sql_type = SmallInt)]
33    struct I16Proxy(i16);
34
35    #[derive(AsExpression, FromSqlRow)]
36    #[diesel(foreign_derive)]
37    #[diesel(sql_type = Integer)]
38    struct I32Proxy(i32);
39
40    #[derive(AsExpression, FromSqlRow)]
41    #[diesel(foreign_derive)]
42    #[diesel(sql_type = BigInt)]
43    struct I64Proxy(i64);
44
45    #[derive(FromSqlRow)]
46    #[cfg_attr(
47        any(feature = "mysql_backend", feature = "postgres_backend"),
48        derive(AsExpression)
49    )]
50    #[diesel(foreign_derive)]
51    #[cfg_attr(
52        feature = "mysql_backend",
53        diesel(sql_type = crate::sql_types::Unsigned<crate::sql_types::TinyInt>)
54    )]
55    #[cfg_attr(feature = "postgres_backend", diesel(foreign_derive, sql_type = crate::sql_types::CChar))]
56    struct U8Proxy(u8);
57
58    #[derive(FromSqlRow)]
59    #[cfg_attr(feature = "mysql_backend", derive(AsExpression))]
60    #[diesel(foreign_derive)]
61    #[cfg_attr(feature = "mysql_backend", diesel(sql_type = crate::sql_types::Unsigned<SmallInt>))]
62    struct U16Proxy(u16);
63
64    #[derive(FromSqlRow)]
65    #[cfg_attr(
66        any(feature = "mysql_backend", feature = "postgres_backend"),
67        derive(AsExpression)
68    )]
69    #[diesel(foreign_derive)]
70    #[cfg_attr(feature = "mysql_backend", diesel(sql_type = crate::sql_types::Unsigned<Integer>))]
71    #[cfg_attr(feature = "postgres_backend", diesel(sql_type = crate::sql_types::Oid))]
72    struct U32Proxy(u32);
73
74    #[derive(FromSqlRow)]
75    #[cfg_attr(feature = "mysql_backend", derive(AsExpression))]
76    #[diesel(foreign_derive)]
77    #[cfg_attr(feature = "mysql_backend", diesel(sql_type = crate::sql_types::Unsigned<BigInt>))]
78    struct U64Proxy(u64);
79
80    #[derive(AsExpression, FromSqlRow)]
81    #[diesel(foreign_derive)]
82    #[diesel(sql_type = Float)]
83    struct F32Proxy(f32);
84
85    #[derive(AsExpression, FromSqlRow)]
86    #[diesel(foreign_derive)]
87    #[diesel(sql_type = Double)]
88    struct F64Proxy(f64);
89
90    #[derive(AsExpression, FromSqlRow)]
91    #[diesel(foreign_derive)]
92    #[diesel(sql_type = Text)]
93    #[cfg_attr(feature = "sqlite", diesel(sql_type = crate::sql_types::Date))]
94    #[cfg_attr(feature = "sqlite", diesel(sql_type = crate::sql_types::Time))]
95    #[cfg_attr(feature = "sqlite", diesel(sql_type = crate::sql_types::Timestamp))]
96    #[cfg_attr(feature = "postgres_backend", diesel(sql_type = crate::sql_types::Citext))]
97    struct StringProxy(String);
98
99    #[derive(AsExpression)]
100    #[diesel(foreign_derive, not_sized)]
101    #[diesel(sql_type = Text)]
102    #[cfg_attr(feature = "sqlite", diesel(sql_type = crate::sql_types::Date))]
103    #[cfg_attr(feature = "sqlite", diesel(sql_type = crate::sql_types::Time))]
104    #[cfg_attr(feature = "sqlite", diesel(sql_type = crate::sql_types::Timestamp))]
105    #[cfg_attr(feature = "postgres_backend", diesel(sql_type = crate::sql_types::Citext))]
106    struct StrProxy(str);
107
108    #[derive(FromSqlRow)]
109    #[diesel(foreign_derive)]
110    struct VecProxy<T>(Vec<T>);
111
112    #[derive(AsExpression)]
113    #[diesel(foreign_derive)]
114    #[diesel(sql_type = Binary)]
115    struct BinaryVecProxy(Vec<u8>);
116
117    #[derive(AsExpression)]
118    #[diesel(foreign_derive, not_sized)]
119    #[diesel(sql_type = Binary)]
120    struct BinarySliceProxy([u8]);
121
122    #[derive(AsExpression)]
123    #[diesel(foreign_derive)]
124    #[diesel(sql_type = Binary)]
125    struct BinaryArrayProxy<const N: usize>([u8; N]);
126}
127
128impl<ST, DB> FromSql<ST, DB> for String
129where
130    DB: Backend,
131    *const str: FromSql<ST, DB>,
132{
133    #[allow(unsafe_code)] // ptr dereferencing
134    fn from_sql(bytes: DB::RawValue<'_>) -> deserialize::Result<Self> {
135        let str_ptr = <*const str as FromSql<ST, DB>>::from_sql(bytes)?;
136        // We know that the pointer impl will never return null
137        let string = unsafe { &*str_ptr };
138        Ok(string.to_owned())
139    }
140}
141
142impl<DB> ToSql<sql_types::Text, DB> for str
143where
144    for<'a> DB: Backend<BindCollector<'a> = RawBytesBindCollector<DB>>,
145{
146    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> serialize::Result {
147        out.write_all(self.as_bytes())
148            .map(|_| IsNull::No)
149            .map_err(|e| Box::new(e) as Box<dyn Error + Send + Sync>)
150    }
151}
152
153impl<DB> ToSql<sql_types::Text, DB> for String
154where
155    DB: Backend,
156    str: ToSql<sql_types::Text, DB>,
157{
158    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> serialize::Result {
159        (self as &str).to_sql(out)
160    }
161}
162
163impl<ST, DB> FromSql<ST, DB> for Vec<u8>
164where
165    DB: Backend,
166    *const [u8]: FromSql<ST, DB>,
167{
168    #[allow(unsafe_code)] // ptr dereferencing
169    fn from_sql(bytes: DB::RawValue<'_>) -> deserialize::Result<Self> {
170        let slice_ptr = <*const [u8] as FromSql<ST, DB>>::from_sql(bytes)?;
171        // We know that the pointer impl will never return null
172        let bytes = unsafe { &*slice_ptr };
173        Ok(bytes.to_owned())
174    }
175}
176
177impl<DB> ToSql<sql_types::Binary, DB> for Vec<u8>
178where
179    DB: Backend,
180    [u8]: ToSql<sql_types::Binary, DB>,
181{
182    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> serialize::Result {
183        (self as &[u8]).to_sql(out)
184    }
185}
186
187impl<DB, const N: usize> ToSql<sql_types::Binary, DB> for [u8; N]
188where
189    DB: Backend,
190    [u8]: ToSql<sql_types::Binary, DB>,
191{
192    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> serialize::Result {
193        self.as_slice().to_sql(out)
194    }
195}
196
197impl<DB> ToSql<sql_types::Binary, DB> for [u8]
198where
199    for<'a> DB: Backend<BindCollector<'a> = RawBytesBindCollector<DB>>,
200{
201    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> serialize::Result {
202        out.write_all(self)
203            .map(|_| IsNull::No)
204            .map_err(|e| Box::new(e) as Box<dyn Error + Send + Sync>)
205    }
206}
207
208impl<'a, T: ?Sized, ST, DB> ToSql<ST, DB> for Cow<'a, T>
209where
210    T: 'a + ToOwned + ToSql<ST, DB>,
211    DB: Backend,
212    Self: fmt::Debug,
213{
214    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> serialize::Result {
215        ToSql::<ST, DB>::to_sql(&**self, out)
216    }
217}
218
219impl<'a, T: ?Sized, ST, DB> FromSql<ST, DB> for Cow<'a, T>
220where
221    T: 'a + ToOwned,
222    DB: Backend,
223    T::Owned: FromSql<ST, DB>,
224{
225    fn from_sql(bytes: DB::RawValue<'_>) -> deserialize::Result<Self> {
226        T::Owned::from_sql(bytes).map(Cow::Owned)
227    }
228}
229
230impl<'a, T: ?Sized, ST, DB> Queryable<ST, DB> for Cow<'a, T>
231where
232    T: 'a + ToOwned,
233    ST: SingleValue,
234    DB: Backend,
235    Self: FromSql<ST, DB>,
236{
237    type Row = Self;
238
239    fn build(row: Self::Row) -> deserialize::Result<Self> {
240        Ok(row)
241    }
242}
243
244use crate::expression::bound::Bound;
245use crate::expression::{AsExpression, Expression, TypedExpressionType};
246use sql_types::SqlType;
247
248impl<'a, T: ?Sized, ST> AsExpression<ST> for Cow<'a, T>
249where
250    T: 'a + ToOwned,
251    Bound<ST, Cow<'a, T>>: Expression<SqlType = ST>,
252    ST: SqlType + TypedExpressionType,
253{
254    type Expression = Bound<ST, Self>;
255
256    fn as_expression(self) -> Self::Expression {
257        Bound::new(self)
258    }
259}
260
261impl<'a, 'b, T: ?Sized, ST> AsExpression<ST> for &'b Cow<'a, T>
262where
263    T: 'a + ToOwned,
264    Bound<ST, &'b T>: Expression<SqlType = ST>,
265    ST: SqlType + TypedExpressionType,
266{
267    type Expression = Bound<ST, &'b T>;
268
269    fn as_expression(self) -> Self::Expression {
270        Bound::new(&**self)
271    }
272}