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)] fn from_sql(bytes: DB::RawValue<'_>) -> deserialize::Result<Self> {
135 let str_ptr = <*const str as FromSql<ST, DB>>::from_sql(bytes)?;
136 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)] fn from_sql(bytes: DB::RawValue<'_>) -> deserialize::Result<Self> {
170 let slice_ptr = <*const [u8] as FromSql<ST, DB>>::from_sql(bytes)?;
171 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}