diesel/type_impls/
primitives.rs

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