1use crate::traits::FromSQLiteValue;
4use drizzle_core::{SQL, ToSQL, error::DrizzleError};
5
6mod insert;
7mod owned;
8pub use insert::*;
9pub use owned::OwnedSQLiteValue;
10
11#[cfg(feature = "rusqlite")]
12use rusqlite::types::FromSql;
13#[cfg(feature = "turso")]
14use turso::IntoValue;
15#[cfg(feature = "uuid")]
16use uuid::Uuid;
17
18use std::borrow::Cow;
19
20#[derive(Debug, Clone, PartialEq, PartialOrd, Default)]
26pub enum SQLiteValue<'a> {
27 Integer(i64),
29 Real(f64),
31 Text(Cow<'a, str>),
33 Blob(Cow<'a, [u8]>),
35 #[default]
37 Null,
38}
39
40impl<'a> SQLiteValue<'a> {
41 pub fn convert<T: FromSQLiteValue>(self) -> Result<T, DrizzleError> {
52 match self {
53 SQLiteValue::Integer(i) => T::from_sqlite_integer(i),
54 SQLiteValue::Text(s) => T::from_sqlite_text(&s),
55 SQLiteValue::Real(r) => T::from_sqlite_real(r),
56 SQLiteValue::Blob(b) => T::from_sqlite_blob(&b),
57 SQLiteValue::Null => T::from_sqlite_null(),
58 }
59 }
60
61 pub fn convert_ref<T: FromSQLiteValue>(&self) -> Result<T, DrizzleError> {
63 match self {
64 SQLiteValue::Integer(i) => T::from_sqlite_integer(*i),
65 SQLiteValue::Text(s) => T::from_sqlite_text(s),
66 SQLiteValue::Real(r) => T::from_sqlite_real(*r),
67 SQLiteValue::Blob(b) => T::from_sqlite_blob(b),
68 SQLiteValue::Null => T::from_sqlite_null(),
69 }
70 }
71}
72
73impl<'a> ToSQL<'a, SQLiteValue<'a>> for SQLiteValue<'a> {
74 fn to_sql(&self) -> SQL<'a, SQLiteValue<'a>> {
75 SQL::param(self.clone())
76 }
77}
78impl<'a> From<OwnedSQLiteValue> for SQLiteValue<'a> {
79 fn from(value: OwnedSQLiteValue) -> Self {
80 match value {
81 OwnedSQLiteValue::Integer(f) => SQLiteValue::Integer(f),
82 OwnedSQLiteValue::Real(r) => SQLiteValue::Real(r),
83 OwnedSQLiteValue::Text(v) => SQLiteValue::Text(Cow::Owned(v)),
84 OwnedSQLiteValue::Blob(v) => SQLiteValue::Blob(Cow::Owned(v.into())),
85 OwnedSQLiteValue::Null => SQLiteValue::Null,
86 }
87 }
88}
89impl<'a> From<&'a OwnedSQLiteValue> for SQLiteValue<'a> {
90 fn from(value: &'a OwnedSQLiteValue) -> Self {
91 match value {
92 OwnedSQLiteValue::Integer(f) => SQLiteValue::Integer(*f),
93 OwnedSQLiteValue::Real(r) => SQLiteValue::Real(*r),
94 OwnedSQLiteValue::Text(v) => SQLiteValue::Text(Cow::Borrowed(v)),
95 OwnedSQLiteValue::Blob(v) => SQLiteValue::Blob(Cow::Borrowed(v)),
96 OwnedSQLiteValue::Null => SQLiteValue::Null,
97 }
98 }
99}
100impl<'a> From<&'a SQLiteValue<'a>> for SQLiteValue<'a> {
101 fn from(value: &'a SQLiteValue<'a>) -> Self {
102 match value {
103 SQLiteValue::Integer(f) => SQLiteValue::Integer(*f),
104 SQLiteValue::Real(r) => SQLiteValue::Real(*r),
105 SQLiteValue::Text(v) => SQLiteValue::Text(Cow::Borrowed(v)),
106 SQLiteValue::Blob(v) => SQLiteValue::Blob(Cow::Borrowed(v)),
107 SQLiteValue::Null => SQLiteValue::Null,
108 }
109 }
110}
111impl<'a> From<Cow<'a, SQLiteValue<'a>>> for SQLiteValue<'a> {
112 fn from(value: Cow<'a, SQLiteValue<'a>>) -> Self {
113 match value {
114 Cow::Borrowed(r) => r.into(),
115 Cow::Owned(o) => o,
116 }
117 }
118}
119impl<'a> From<&'a Cow<'a, SQLiteValue<'a>>> for SQLiteValue<'a> {
120 fn from(value: &'a Cow<'a, SQLiteValue<'a>>) -> Self {
121 match value {
122 Cow::Borrowed(r) => (*r).into(),
123 Cow::Owned(o) => o.into(),
124 }
125 }
126}
127
128impl<'a> std::fmt::Display for SQLiteValue<'a> {
129 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
130 let value = match self {
131 SQLiteValue::Integer(i) => i.to_string(),
132 SQLiteValue::Real(r) => r.to_string(),
133 SQLiteValue::Text(cow) => cow.to_string(),
134 SQLiteValue::Blob(cow) => String::from_utf8_lossy(cow).to_string(),
135 SQLiteValue::Null => String::new(),
136 };
137 write!(f, "{value}")
138 }
139}
140
141impl<'a> From<SQL<'a, SQLiteValue<'a>>> for SQLiteValue<'a> {
142 fn from(_value: SQL<'a, SQLiteValue<'a>>) -> Self {
143 unimplemented!()
144 }
145}
146
147impl<'a> FromIterator<OwnedSQLiteValue> for Vec<SQLiteValue<'a>> {
148 fn from_iter<T: IntoIterator<Item = OwnedSQLiteValue>>(iter: T) -> Self {
149 iter.into_iter().map(SQLiteValue::from).collect()
150 }
151}
152
153impl<'a> FromIterator<&'a OwnedSQLiteValue> for Vec<SQLiteValue<'a>> {
154 fn from_iter<T: IntoIterator<Item = &'a OwnedSQLiteValue>>(iter: T) -> Self {
155 iter.into_iter().map(SQLiteValue::from).collect()
156 }
157}
158
159#[cfg(feature = "rusqlite")]
165impl<'a> rusqlite::ToSql for SQLiteValue<'a> {
166 fn to_sql(&self) -> ::rusqlite::Result<::rusqlite::types::ToSqlOutput<'_>> {
167 match self {
168 SQLiteValue::Null => Ok(rusqlite::types::ToSqlOutput::Owned(
169 rusqlite::types::Value::Null,
170 )),
171 SQLiteValue::Integer(i) => Ok(rusqlite::types::ToSqlOutput::Owned(
172 rusqlite::types::Value::Integer(*i),
173 )),
174 SQLiteValue::Real(f) => Ok(rusqlite::types::ToSqlOutput::Owned(
175 rusqlite::types::Value::Real(*f),
176 )),
177 SQLiteValue::Text(s) => Ok(rusqlite::types::ToSqlOutput::Borrowed(
178 rusqlite::types::ValueRef::Text(s.as_bytes()),
179 )),
180 SQLiteValue::Blob(b) => Ok(rusqlite::types::ToSqlOutput::Borrowed(
181 rusqlite::types::ValueRef::Blob(b.as_ref()),
182 )),
183 }
184 }
185}
186
187#[cfg(feature = "rusqlite")]
188impl<'a> FromSql for SQLiteValue<'a> {
189 fn column_result(value: rusqlite::types::ValueRef<'_>) -> rusqlite::types::FromSqlResult<Self> {
190 let result = match value {
191 rusqlite::types::ValueRef::Null => SQLiteValue::Null,
192 rusqlite::types::ValueRef::Integer(i) => SQLiteValue::Integer(i),
193 rusqlite::types::ValueRef::Real(r) => SQLiteValue::Real(r),
194 rusqlite::types::ValueRef::Text(items) => {
195 SQLiteValue::Text(String::from_utf8_lossy(items).into_owned().into())
196 }
197 rusqlite::types::ValueRef::Blob(items) => SQLiteValue::Blob(items.to_vec().into()),
198 };
199 Ok(result)
200 }
201}
202
203#[cfg(feature = "rusqlite")]
204impl<'a> From<rusqlite::types::Value> for SQLiteValue<'a> {
205 fn from(value: rusqlite::types::Value) -> Self {
206 match value {
207 rusqlite::types::Value::Null => SQLiteValue::Null,
208 rusqlite::types::Value::Integer(i) => SQLiteValue::Integer(i),
209 rusqlite::types::Value::Real(r) => SQLiteValue::Real(r),
210 rusqlite::types::Value::Text(s) => SQLiteValue::Text(s.into()),
211 rusqlite::types::Value::Blob(b) => SQLiteValue::Blob(b.into()),
212 }
213 }
214}
215
216#[cfg(feature = "rusqlite")]
217impl<'a> From<rusqlite::types::ValueRef<'a>> for SQLiteValue<'a> {
218 fn from(value: rusqlite::types::ValueRef<'a>) -> Self {
219 match value {
220 rusqlite::types::ValueRef::Null => SQLiteValue::Null,
221 rusqlite::types::ValueRef::Integer(i) => SQLiteValue::Integer(i),
222 rusqlite::types::ValueRef::Real(r) => SQLiteValue::Real(r),
223 rusqlite::types::ValueRef::Text(items) => {
224 SQLiteValue::Text(String::from_utf8_lossy(items).into_owned().into())
225 }
226 rusqlite::types::ValueRef::Blob(items) => SQLiteValue::Blob(items.to_vec().into()),
227 }
228 }
229}
230
231#[cfg(feature = "turso")]
232impl<'a> IntoValue for SQLiteValue<'a> {
233 fn into_value(self) -> turso::Result<turso::Value> {
234 let result = match self {
235 SQLiteValue::Integer(i) => turso::Value::Integer(i),
236 SQLiteValue::Real(r) => turso::Value::Real(r),
237 SQLiteValue::Text(cow) => turso::Value::Text(cow.into()),
238 SQLiteValue::Blob(cow) => turso::Value::Blob(cow.into()),
239 SQLiteValue::Null => turso::Value::Null,
240 };
241 Ok(result)
242 }
243}
244
245#[cfg(feature = "turso")]
246impl<'a> IntoValue for &SQLiteValue<'a> {
247 fn into_value(self) -> turso::Result<turso::Value> {
248 let result = match self {
249 SQLiteValue::Integer(i) => turso::Value::Integer(*i),
250 SQLiteValue::Real(r) => turso::Value::Real(*r),
251 SQLiteValue::Text(cow) => turso::Value::Text(cow.to_string()),
252 SQLiteValue::Blob(cow) => turso::Value::Blob(cow.to_vec()),
253 SQLiteValue::Null => turso::Value::Null,
254 };
255 Ok(result)
256 }
257}
258
259#[cfg(feature = "turso")]
260impl<'a> From<SQLiteValue<'a>> for turso::Value {
261 fn from(value: SQLiteValue<'a>) -> Self {
262 match value {
263 SQLiteValue::Integer(i) => turso::Value::Integer(i),
264 SQLiteValue::Real(r) => turso::Value::Real(r),
265 SQLiteValue::Text(cow) => turso::Value::Text(cow.to_string()),
266 SQLiteValue::Blob(cow) => turso::Value::Blob(cow.to_vec()),
267 SQLiteValue::Null => turso::Value::Null,
268 }
269 }
270}
271
272#[cfg(feature = "turso")]
273impl<'a> From<&SQLiteValue<'a>> for turso::Value {
274 fn from(value: &SQLiteValue<'a>) -> Self {
275 match value {
276 SQLiteValue::Integer(i) => turso::Value::Integer(*i),
277 SQLiteValue::Real(r) => turso::Value::Real(*r),
278 SQLiteValue::Text(cow) => turso::Value::Text(cow.to_string()),
279 SQLiteValue::Blob(cow) => turso::Value::Blob(cow.to_vec()),
280 SQLiteValue::Null => turso::Value::Null,
281 }
282 }
283}
284
285#[cfg(feature = "libsql")]
286impl<'a> From<SQLiteValue<'a>> for libsql::Value {
287 fn from(value: SQLiteValue<'a>) -> Self {
288 match value {
289 SQLiteValue::Integer(i) => libsql::Value::Integer(i),
290 SQLiteValue::Real(r) => libsql::Value::Real(r),
291 SQLiteValue::Text(cow) => libsql::Value::Text(cow.to_string()),
292 SQLiteValue::Blob(cow) => libsql::Value::Blob(cow.to_vec()),
293 SQLiteValue::Null => libsql::Value::Null,
294 }
295 }
296}
297
298#[cfg(feature = "libsql")]
299impl<'a> From<&SQLiteValue<'a>> for libsql::Value {
300 fn from(value: &SQLiteValue<'a>) -> Self {
301 match value {
302 SQLiteValue::Integer(i) => libsql::Value::Integer(*i),
303 SQLiteValue::Real(r) => libsql::Value::Real(*r),
304 SQLiteValue::Text(cow) => libsql::Value::Text(cow.to_string()),
305 SQLiteValue::Blob(cow) => libsql::Value::Blob(cow.to_vec()),
306 SQLiteValue::Null => libsql::Value::Null,
307 }
308 }
309}
310
311impl<'a> drizzle_core::traits::SQLParam for SQLiteValue<'a> {}
313
314impl<'a> From<SQLiteValue<'a>> for SQL<'a, SQLiteValue<'a>> {
315 fn from(value: SQLiteValue<'a>) -> Self {
316 SQL::param(value)
317 }
318}
319
320macro_rules! impl_from_int_for_sqlite_value {
327 ($($ty:ty),* $(,)?) => {
328 $(
329 impl<'a> From<$ty> for SQLiteValue<'a> {
330 #[inline]
331 fn from(value: $ty) -> Self {
332 SQLiteValue::Integer(value as i64)
333 }
334 }
335
336 impl<'a> From<&$ty> for SQLiteValue<'a> {
337 #[inline]
338 fn from(value: &$ty) -> Self {
339 SQLiteValue::Integer(*value as i64)
340 }
341 }
342 )*
343 };
344}
345
346macro_rules! impl_from_float_for_sqlite_value {
348 ($($ty:ty),* $(,)?) => {
349 $(
350 impl<'a> From<$ty> for SQLiteValue<'a> {
351 #[inline]
352 fn from(value: $ty) -> Self {
353 SQLiteValue::Real(value as f64)
354 }
355 }
356
357 impl<'a> From<&$ty> for SQLiteValue<'a> {
358 #[inline]
359 fn from(value: &$ty) -> Self {
360 SQLiteValue::Real(*value as f64)
361 }
362 }
363 )*
364 };
365}
366
367impl_from_int_for_sqlite_value!(i8, i16, i32, i64, isize, u8, u16, u32, u64, usize, bool);
369
370impl_from_float_for_sqlite_value!(f32, f64);
372
373impl<'a> From<&'a str> for SQLiteValue<'a> {
376 fn from(value: &'a str) -> Self {
377 SQLiteValue::Text(Cow::Borrowed(value))
378 }
379}
380
381impl<'a> From<String> for SQLiteValue<'a> {
382 fn from(value: String) -> Self {
383 SQLiteValue::Text(Cow::Owned(value))
384 }
385}
386
387impl<'a> From<&'a String> for SQLiteValue<'a> {
388 fn from(value: &'a String) -> Self {
389 SQLiteValue::Text(Cow::Borrowed(value))
390 }
391}
392
393impl<'a> From<&'a [u8]> for SQLiteValue<'a> {
396 fn from(value: &'a [u8]) -> Self {
397 SQLiteValue::Blob(Cow::Borrowed(value))
398 }
399}
400
401impl<'a> From<Vec<u8>> for SQLiteValue<'a> {
402 fn from(value: Vec<u8>) -> Self {
403 SQLiteValue::Blob(Cow::Owned(value))
404 }
405}
406
407#[cfg(feature = "uuid")]
410impl<'a> From<Uuid> for SQLiteValue<'a> {
411 fn from(value: Uuid) -> Self {
412 SQLiteValue::Blob(Cow::Owned(value.as_bytes().to_vec()))
413 }
414}
415
416#[cfg(feature = "uuid")]
417impl<'a> From<&'a Uuid> for SQLiteValue<'a> {
418 fn from(value: &'a Uuid) -> Self {
419 SQLiteValue::Blob(Cow::Borrowed(value.as_bytes()))
420 }
421}
422
423impl<'a, T> From<Option<T>> for SQLiteValue<'a>
430where
431 T: TryInto<SQLiteValue<'a>>,
432{
433 fn from(value: Option<T>) -> Self {
434 match value {
435 Some(value) => value.try_into().unwrap_or(SQLiteValue::Null),
436 None => SQLiteValue::Null,
437 }
438 }
439}
440
441impl<'a> From<SQLiteValue<'a>> for Cow<'a, SQLiteValue<'a>> {
443 fn from(value: SQLiteValue<'a>) -> Self {
444 Cow::Owned(value)
445 }
446}
447
448impl<'a> From<&'a SQLiteValue<'a>> for Cow<'a, SQLiteValue<'a>> {
449 fn from(value: &'a SQLiteValue<'a>) -> Self {
450 Cow::Borrowed(value)
451 }
452}
453
454macro_rules! impl_try_from_sqlite_value {
461 ($($ty:ty),* $(,)?) => {
462 $(
463 impl<'a> TryFrom<SQLiteValue<'a>> for $ty {
464 type Error = DrizzleError;
465
466 #[inline]
467 fn try_from(value: SQLiteValue<'a>) -> Result<Self, Self::Error> {
468 value.convert()
469 }
470 }
471 )*
472 };
473}
474
475impl_try_from_sqlite_value!(
476 i8,
477 i16,
478 i32,
479 i64,
480 isize,
481 u8,
482 u16,
483 u32,
484 u64,
485 usize,
486 f32,
487 f64,
488 bool,
489 String,
490 Vec<u8>,
491);
492
493#[cfg(feature = "uuid")]
494impl_try_from_sqlite_value!(Uuid);
495
496macro_rules! impl_try_from_sqlite_value_ref {
503 ($($ty:ty),* $(,)?) => {
504 $(
505 impl<'a> TryFrom<&SQLiteValue<'a>> for $ty {
506 type Error = DrizzleError;
507
508 #[inline]
509 fn try_from(value: &SQLiteValue<'a>) -> Result<Self, Self::Error> {
510 value.convert_ref()
511 }
512 }
513 )*
514 };
515}
516
517impl_try_from_sqlite_value_ref!(
518 i8,
519 i16,
520 i32,
521 i64,
522 isize,
523 u8,
524 u16,
525 u32,
526 u64,
527 usize,
528 f32,
529 f64,
530 bool,
531 String,
532 Vec<u8>,
533);
534
535#[cfg(feature = "uuid")]
536impl_try_from_sqlite_value_ref!(Uuid);
537
538impl<'a> TryFrom<&'a SQLiteValue<'a>> for &'a str {
541 type Error = DrizzleError;
542
543 fn try_from(value: &'a SQLiteValue<'a>) -> Result<Self, Self::Error> {
544 match value {
545 SQLiteValue::Text(cow) => Ok(cow.as_ref()),
546 _ => Err(DrizzleError::ConversionError(
547 format!("Cannot convert {:?} to &str", value).into(),
548 )),
549 }
550 }
551}
552
553impl<'a> TryFrom<&'a SQLiteValue<'a>> for &'a [u8] {
554 type Error = DrizzleError;
555
556 fn try_from(value: &'a SQLiteValue<'a>) -> Result<Self, Self::Error> {
557 match value {
558 SQLiteValue::Blob(cow) => Ok(cow.as_ref()),
559 _ => Err(DrizzleError::ConversionError(
560 format!("Cannot convert {:?} to &[u8]", value).into(),
561 )),
562 }
563 }
564}