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
128#[diagnostic::do_not_recommend]
129impl<ST, DB> FromSql<ST, DB> for String
130where
131 DB: Backend,
132 *const str: FromSql<ST, DB>,
133{
134 #[allow(unsafe_code)] fn from_sql(bytes: DB::RawValue<'_>) -> deserialize::Result<Self> {
136 let str_ptr = <*const str as FromSql<ST, DB>>::from_sql(bytes)?;
137 let string = unsafe { &*str_ptr };
139 Ok(string.to_owned())
140 }
141}
142
143impl<DB> ToSql<sql_types::Text, DB> for str
144where
145 for<'a> DB: Backend<BindCollector<'a> = RawBytesBindCollector<DB>>,
146{
147 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> serialize::Result {
148 out.write_all(self.as_bytes())
149 .map(|_| IsNull::No)
150 .map_err(|e| Box::new(e) as Box<dyn Error + Send + Sync>)
151 }
152}
153
154impl<DB> ToSql<sql_types::Text, DB> for String
155where
156 DB: Backend,
157 str: ToSql<sql_types::Text, DB>,
158{
159 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> serialize::Result {
160 (self as &str).to_sql(out)
161 }
162}
163
164impl<ST, DB> FromSql<ST, DB> for Vec<u8>
165where
166 DB: Backend,
167 *const [u8]: FromSql<ST, DB>,
168{
169 #[allow(unsafe_code)] fn from_sql(bytes: DB::RawValue<'_>) -> deserialize::Result<Self> {
171 let slice_ptr = <*const [u8] as FromSql<ST, DB>>::from_sql(bytes)?;
172 let bytes = unsafe { &*slice_ptr };
174 Ok(bytes.to_owned())
175 }
176}
177
178impl<DB> ToSql<sql_types::Binary, DB> for Vec<u8>
179where
180 DB: Backend,
181 [u8]: ToSql<sql_types::Binary, DB>,
182{
183 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> serialize::Result {
184 (self as &[u8]).to_sql(out)
185 }
186}
187
188impl<DB, const N: usize> ToSql<sql_types::Binary, DB> for [u8; N]
189where
190 DB: Backend,
191 [u8]: ToSql<sql_types::Binary, DB>,
192{
193 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> serialize::Result {
194 self.as_slice().to_sql(out)
195 }
196}
197
198impl<DB> ToSql<sql_types::Binary, DB> for [u8]
199where
200 for<'a> DB: Backend<BindCollector<'a> = RawBytesBindCollector<DB>>,
201{
202 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> serialize::Result {
203 out.write_all(self)
204 .map(|_| IsNull::No)
205 .map_err(|e| Box::new(e) as Box<dyn Error + Send + Sync>)
206 }
207}
208
209impl<'a, T: ?Sized, ST, DB> ToSql<ST, DB> for Cow<'a, T>
210where
211 T: 'a + ToOwned + ToSql<ST, DB>,
212 DB: Backend,
213 Self: fmt::Debug,
214{
215 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> serialize::Result {
216 ToSql::<ST, DB>::to_sql(&**self, out)
217 }
218}
219
220impl<'a, T: ?Sized, ST, DB> FromSql<ST, DB> for Cow<'a, T>
221where
222 T: 'a + ToOwned,
223 DB: Backend,
224 T::Owned: FromSql<ST, DB>,
225{
226 fn from_sql(bytes: DB::RawValue<'_>) -> deserialize::Result<Self> {
227 T::Owned::from_sql(bytes).map(Cow::Owned)
228 }
229}
230
231impl<'a, T: ?Sized, ST, DB> Queryable<ST, DB> for Cow<'a, T>
232where
233 T: 'a + ToOwned,
234 ST: SingleValue,
235 DB: Backend,
236 Self: FromSql<ST, DB>,
237{
238 type Row = Self;
239
240 fn build(row: Self::Row) -> deserialize::Result<Self> {
241 Ok(row)
242 }
243}
244
245use crate::expression::bound::Bound;
246use crate::expression::{AsExpression, Expression, TypedExpressionType};
247use sql_types::SqlType;
248
249impl<'a, T: ?Sized, ST> AsExpression<ST> for Cow<'a, T>
250where
251 T: 'a + ToOwned,
252 Bound<ST, Cow<'a, T>>: Expression<SqlType = ST>,
253 ST: SqlType + TypedExpressionType,
254{
255 type Expression = Bound<ST, Self>;
256
257 fn as_expression(self) -> Self::Expression {
258 Bound::new(self)
259 }
260}
261
262impl<'a, 'b, T: ?Sized, ST> AsExpression<ST> for &'b Cow<'a, T>
263where
264 T: 'a + ToOwned,
265 Bound<ST, &'b T>: Expression<SqlType = ST>,
266 ST: SqlType + TypedExpressionType,
267{
268 type Expression = Bound<ST, &'b T>;
269
270 fn as_expression(self) -> Self::Expression {
271 Bound::new(&**self)
272 }
273}