1use crate::prelude::*;
7use crate::values::{OwnedSQLiteValue, SQLiteValue, SQLiteValueRef};
8use drizzle_core::conv::checked_float_to_int;
9use drizzle_core::error::DrizzleError;
10
11#[diagnostic::on_unimplemented(
31 message = "`{Self}` cannot be used as a SQLite column type",
32 note = "add #[derive(SQLiteEnum)] for enum types, or use a supported primitive type"
33)]
34pub trait DrizzleSQLiteColumn: Sized {
35 type SQLType: drizzle_core::types::DataType;
40
41 const SQL_TYPE: &'static str;
43
44 fn decode(value: SQLiteValueRef<'_>) -> Result<Self, DrizzleError>;
54
55 fn encode(&self) -> SQLiteValue<'_>;
57
58 fn encode_owned(self) -> OwnedSQLiteValue {
64 self.encode().into_owned()
65 }
66}
67
68impl<'a, T> From<T> for SQLiteValue<'a>
69where
70 T: DrizzleSQLiteColumn,
71{
72 fn from(value: T) -> Self {
73 value.encode_owned().into()
74 }
75}
76
77pub trait FromSQLiteValue: Sized {
88 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError>;
94
95 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError>;
101
102 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError>;
108
109 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError>;
115
116 fn from_sqlite_ref(value: SQLiteValueRef<'_>) -> Result<Self, DrizzleError> {
123 match value {
124 SQLiteValueRef::Integer(value) => Self::from_sqlite_integer(value),
125 SQLiteValueRef::Text(value) => Self::from_sqlite_text(value),
126 SQLiteValueRef::Real(value) => Self::from_sqlite_real(value),
127 SQLiteValueRef::Blob(value) => Self::from_sqlite_blob(value),
128 SQLiteValueRef::Null => Self::from_sqlite_null(),
129 }
130 }
131
132 fn from_sqlite_null() -> Result<Self, DrizzleError> {
139 Err(DrizzleError::ConversionError(
140 "unexpected NULL value".into(),
141 ))
142 }
143
144 #[cfg(feature = "rusqlite")]
151 fn from_value_ref(value: ::rusqlite::types::ValueRef<'_>) -> Result<Self, DrizzleError> {
152 let value = SQLiteValueRef::try_from_rusqlite_value_ref(value)?;
153 Self::from_sqlite_ref(value)
154 }
155}
156
157impl<T> FromSQLiteValue for T
158where
159 T: DrizzleSQLiteColumn,
160{
161 fn from_sqlite_ref(value: SQLiteValueRef<'_>) -> Result<Self, DrizzleError> {
162 T::decode(value)
163 }
164
165 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
166 T::decode(SQLiteValueRef::Integer(value))
167 }
168
169 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
170 T::decode(SQLiteValueRef::Text(value))
171 }
172
173 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
174 T::decode(SQLiteValueRef::Real(value))
175 }
176
177 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
178 T::decode(SQLiteValueRef::Blob(value))
179 }
180
181 fn from_sqlite_null() -> Result<Self, DrizzleError> {
182 T::decode(SQLiteValueRef::Null)
183 }
184}
185
186pub trait DrizzleRowByIndex {
188 fn get_column<T: FromSQLiteValue>(&self, idx: usize) -> Result<T, DrizzleError>;
195}
196
197pub trait DrizzleRowByName: DrizzleRowByIndex {
199 fn get_column_by_name<T: FromSQLiteValue>(&self, name: &str) -> Result<T, DrizzleError>;
206}
207
208macro_rules! impl_from_sqlite_value_int {
214 (i64) => {
216 impl FromSQLiteValue for i64 {
217 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
218 Ok(value)
219 }
220
221 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
222 value.parse().map_err(|e| {
223 DrizzleError::ConversionError(format!("cannot parse '{}' as i64: {}", value, e).into())
224 })
225 }
226
227 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
228 checked_float_to_int(value, "i64")
229 }
230
231 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
232 Err(DrizzleError::ConversionError("cannot convert BLOB to i64".into()))
233 }
234 }
235 };
236 ($($ty:ty),+ $(,)?) => {
238 $(
239 impl FromSQLiteValue for $ty {
240 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
241 value.try_into().map_err(|e| {
242 DrizzleError::ConversionError(
243 format!("i64 {} out of range for {}: {}", value, stringify!($ty), e).into(),
244 )
245 })
246 }
247
248 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
249 value.parse().map_err(|e| {
250 DrizzleError::ConversionError(
251 format!("cannot parse '{}' as {}: {}", value, stringify!($ty), e).into()
252 )
253 })
254 }
255
256 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
257 checked_float_to_int(value, stringify!($ty))
258 }
259
260 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
261 Err(DrizzleError::ConversionError(
262 concat!("cannot convert BLOB to ", stringify!($ty)).into()
263 ))
264 }
265 }
266 )+
267 };
268}
269
270#[inline]
273fn i64_to_f64(i: i64) -> f64 {
274 let high = i32::try_from(i >> 32).expect("sign-extended high word fits in i32");
275 let low = u32::try_from(i & 0xFFFF_FFFF).expect("masked low word fits in u32");
276 f64::from(high) * 4_294_967_296.0_f64 + f64::from(low)
277}
278
279impl_from_sqlite_value_int!(i64);
281impl_from_sqlite_value_int!(i8, i16, i32, isize, u8, u16, u32, u64, usize);
282
283impl FromSQLiteValue for f64 {
286 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
287 Ok(i64_to_f64(value))
288 }
289
290 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
291 value.parse().map_err(|e| {
292 DrizzleError::ConversionError(format!("cannot parse '{value}' as f64: {e}").into())
293 })
294 }
295
296 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
297 Ok(value)
298 }
299
300 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
301 Err(DrizzleError::ConversionError(
302 "cannot convert BLOB to f64".into(),
303 ))
304 }
305}
306
307fn narrow_to_f32(value: f64) -> Result<f32, DrizzleError> {
308 format!("{value}").parse::<f32>().map_err(|e| {
312 DrizzleError::ConversionError(format!("cannot convert REAL {value} to f32: {e}").into())
313 })
314}
315
316impl FromSQLiteValue for f32 {
320 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
321 narrow_to_f32(i64_to_f64(value))
323 }
324
325 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
326 value.parse().map_err(|e| {
327 DrizzleError::ConversionError(format!("cannot parse '{value}' as f32: {e}").into())
328 })
329 }
330
331 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
332 narrow_to_f32(value)
333 }
334
335 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
336 Err(DrizzleError::ConversionError(
337 "cannot convert BLOB to f32".into(),
338 ))
339 }
340}
341
342impl FromSQLiteValue for bool {
343 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
344 Ok(value != 0)
345 }
346
347 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
348 match value.to_lowercase().as_str() {
349 "true" | "1" | "yes" | "on" => Ok(true),
350 "false" | "0" | "no" | "off" => Ok(false),
351 _ => Err(DrizzleError::ConversionError(
352 format!("cannot parse '{value}' as bool").into(),
353 )),
354 }
355 }
356
357 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
358 Ok(value != 0.0)
359 }
360
361 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
362 Err(DrizzleError::ConversionError(
363 "cannot convert BLOB to bool".into(),
364 ))
365 }
366}
367
368impl FromSQLiteValue for String {
369 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
370 Ok(value.to_string())
371 }
372
373 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
374 Ok(value.to_string())
375 }
376
377 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
378 Ok(value.to_string())
379 }
380
381 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
382 Self::from_utf8(value.to_vec()).map_err(|e| {
383 DrizzleError::ConversionError(format!("invalid UTF-8 in BLOB: {e}").into())
384 })
385 }
386}
387
388impl FromSQLiteValue for compact_str::CompactString {
389 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
390 Ok(Self::new(value.to_string()))
391 }
392
393 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
394 Ok(Self::new(value))
395 }
396
397 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
398 Ok(Self::new(value.to_string()))
399 }
400
401 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
402 let s = String::from_utf8(value.to_vec()).map_err(|e| {
403 DrizzleError::ConversionError(format!("invalid UTF-8 in BLOB: {e}").into())
404 })?;
405 Ok(Self::new(s))
406 }
407}
408
409impl FromSQLiteValue for Box<String> {
410 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
411 String::from_sqlite_integer(value).map(Self::new)
412 }
413
414 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
415 String::from_sqlite_text(value).map(Self::new)
416 }
417
418 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
419 String::from_sqlite_real(value).map(Self::new)
420 }
421
422 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
423 String::from_sqlite_blob(value).map(Self::new)
424 }
425}
426
427impl FromSQLiteValue for Rc<String> {
428 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
429 String::from_sqlite_integer(value).map(Self::new)
430 }
431
432 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
433 String::from_sqlite_text(value).map(Self::new)
434 }
435
436 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
437 String::from_sqlite_real(value).map(Self::new)
438 }
439
440 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
441 String::from_sqlite_blob(value).map(Self::new)
442 }
443}
444
445impl FromSQLiteValue for Arc<String> {
446 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
447 String::from_sqlite_integer(value).map(Self::new)
448 }
449
450 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
451 String::from_sqlite_text(value).map(Self::new)
452 }
453
454 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
455 String::from_sqlite_real(value).map(Self::new)
456 }
457
458 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
459 String::from_sqlite_blob(value).map(Self::new)
460 }
461}
462
463impl FromSQLiteValue for Box<str> {
464 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
465 String::from_sqlite_integer(value).map(String::into_boxed_str)
466 }
467
468 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
469 String::from_sqlite_text(value).map(String::into_boxed_str)
470 }
471
472 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
473 String::from_sqlite_real(value).map(String::into_boxed_str)
474 }
475
476 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
477 String::from_sqlite_blob(value).map(String::into_boxed_str)
478 }
479}
480
481impl FromSQLiteValue for Rc<str> {
482 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
483 String::from_sqlite_integer(value).map(Self::from)
484 }
485
486 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
487 String::from_sqlite_text(value).map(Self::from)
488 }
489
490 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
491 String::from_sqlite_real(value).map(Self::from)
492 }
493
494 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
495 String::from_sqlite_blob(value).map(Self::from)
496 }
497}
498
499impl FromSQLiteValue for Arc<str> {
500 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
501 String::from_sqlite_integer(value).map(Self::from)
502 }
503
504 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
505 String::from_sqlite_text(value).map(Self::from)
506 }
507
508 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
509 String::from_sqlite_real(value).map(Self::from)
510 }
511
512 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
513 String::from_sqlite_blob(value).map(Self::from)
514 }
515}
516
517impl FromSQLiteValue for Vec<u8> {
518 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
519 Ok(value.to_le_bytes().to_vec())
520 }
521
522 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
523 Ok(value.as_bytes().to_vec())
524 }
525
526 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
527 Ok(value.to_le_bytes().to_vec())
528 }
529
530 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
531 Ok(value.to_vec())
532 }
533}
534
535#[cfg(feature = "bytes")]
536impl FromSQLiteValue for bytes::Bytes {
537 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
538 Vec::<u8>::from_sqlite_integer(value).map(Self::from)
539 }
540
541 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
542 Vec::<u8>::from_sqlite_text(value).map(Self::from)
543 }
544
545 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
546 Vec::<u8>::from_sqlite_real(value).map(Self::from)
547 }
548
549 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
550 Ok(Self::copy_from_slice(value))
551 }
552}
553
554#[cfg(feature = "bytes")]
555impl FromSQLiteValue for bytes::BytesMut {
556 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
557 Vec::<u8>::from_sqlite_integer(value).map(|v| Self::from(v.as_slice()))
558 }
559
560 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
561 Vec::<u8>::from_sqlite_text(value).map(|v| Self::from(v.as_slice()))
562 }
563
564 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
565 Vec::<u8>::from_sqlite_real(value).map(|v| Self::from(v.as_slice()))
566 }
567
568 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
569 Ok(Self::from(value))
570 }
571}
572
573#[cfg(feature = "smallvec")]
574impl<const N: usize> FromSQLiteValue for smallvec::SmallVec<[u8; N]> {
575 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
576 Err(DrizzleError::ConversionError(
577 "cannot convert INTEGER to SmallVec<u8>, use BLOB".into(),
578 ))
579 }
580
581 fn from_sqlite_text(_value: &str) -> Result<Self, DrizzleError> {
582 Err(DrizzleError::ConversionError(
583 "cannot convert TEXT to SmallVec<u8>, use BLOB".into(),
584 ))
585 }
586
587 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
588 Err(DrizzleError::ConversionError(
589 "cannot convert REAL to SmallVec<u8>, use BLOB".into(),
590 ))
591 }
592
593 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
594 let mut out = Self::new();
595 out.extend_from_slice(value);
596 Ok(out)
597 }
598}
599
600impl FromSQLiteValue for Box<Vec<u8>> {
601 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
602 Vec::<u8>::from_sqlite_integer(value).map(Self::new)
603 }
604
605 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
606 Vec::<u8>::from_sqlite_text(value).map(Self::new)
607 }
608
609 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
610 Vec::<u8>::from_sqlite_real(value).map(Self::new)
611 }
612
613 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
614 Vec::<u8>::from_sqlite_blob(value).map(Self::new)
615 }
616}
617
618impl FromSQLiteValue for Rc<Vec<u8>> {
619 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
620 Vec::<u8>::from_sqlite_integer(value).map(Self::new)
621 }
622
623 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
624 Vec::<u8>::from_sqlite_text(value).map(Self::new)
625 }
626
627 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
628 Vec::<u8>::from_sqlite_real(value).map(Self::new)
629 }
630
631 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
632 Vec::<u8>::from_sqlite_blob(value).map(Self::new)
633 }
634}
635
636impl FromSQLiteValue for Arc<Vec<u8>> {
637 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
638 Vec::<u8>::from_sqlite_integer(value).map(Self::new)
639 }
640
641 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
642 Vec::<u8>::from_sqlite_text(value).map(Self::new)
643 }
644
645 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
646 Vec::<u8>::from_sqlite_real(value).map(Self::new)
647 }
648
649 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
650 Vec::<u8>::from_sqlite_blob(value).map(Self::new)
651 }
652}
653
654impl<T: FromSQLiteValue> FromSQLiteValue for Option<T> {
656 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
657 T::from_sqlite_integer(value).map(Some)
658 }
659
660 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
661 T::from_sqlite_text(value).map(Some)
662 }
663
664 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
665 T::from_sqlite_real(value).map(Some)
666 }
667
668 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
669 T::from_sqlite_blob(value).map(Some)
670 }
671
672 fn from_sqlite_null() -> Result<Self, DrizzleError> {
673 Ok(None)
674 }
675}
676
677#[cfg(feature = "rusqlite")]
682impl DrizzleRowByIndex for rusqlite::Row<'_> {
683 fn get_column<T: FromSQLiteValue>(&self, idx: usize) -> Result<T, DrizzleError> {
684 let value_ref = self.get_ref(idx)?;
685 match value_ref {
686 rusqlite::types::ValueRef::Integer(i) => T::from_sqlite_integer(i),
687 rusqlite::types::ValueRef::Text(s) => {
688 let s = core::str::from_utf8(s).map_err(|e| {
689 DrizzleError::ConversionError(format!("invalid UTF-8: {e}").into())
690 })?;
691 T::from_sqlite_text(s)
692 }
693 rusqlite::types::ValueRef::Real(r) => T::from_sqlite_real(r),
694 rusqlite::types::ValueRef::Blob(b) => T::from_sqlite_blob(b),
695 rusqlite::types::ValueRef::Null => T::from_sqlite_null(),
696 }
697 }
698}
699
700#[cfg(feature = "rusqlite")]
701impl DrizzleRowByName for rusqlite::Row<'_> {
702 fn get_column_by_name<T: FromSQLiteValue>(&self, name: &str) -> Result<T, DrizzleError> {
703 let idx = self.as_ref().column_index(name)?;
704 DrizzleRowByIndex::get_column(self, idx)
705 }
706}
707
708#[cfg(feature = "libsql")]
709impl DrizzleRowByIndex for libsql::Row {
710 fn get_column<T: FromSQLiteValue>(&self, idx: usize) -> Result<T, DrizzleError> {
711 let idx_i32 = i32::try_from(idx).map_err(|e| {
712 DrizzleError::ConversionError(format!("column index {idx} out of range: {e}").into())
713 })?;
714 let value = self.get_value(idx_i32)?;
715 match value {
716 libsql::Value::Integer(i) => T::from_sqlite_integer(i),
717 libsql::Value::Text(ref s) => T::from_sqlite_text(s),
718 libsql::Value::Real(r) => T::from_sqlite_real(r),
719 libsql::Value::Blob(ref b) => T::from_sqlite_blob(b),
720 libsql::Value::Null => T::from_sqlite_null(),
721 }
722 }
723}
724
725#[cfg(feature = "libsql")]
726impl DrizzleRowByName for libsql::Row {
727 fn get_column_by_name<T: FromSQLiteValue>(&self, name: &str) -> Result<T, DrizzleError> {
728 let idx = (0..self.column_count())
729 .find(|&i| self.column_name(i) == Some(name))
730 .ok_or_else(|| {
731 DrizzleError::ConversionError(format!("column '{name}' not found").into())
732 })?;
733
734 let idx_usize = usize::try_from(idx).map_err(|e| {
735 DrizzleError::ConversionError(format!("column index {idx} negative: {e}").into())
736 })?;
737 DrizzleRowByIndex::get_column(self, idx_usize)
738 }
739}
740
741#[cfg(feature = "turso")]
742impl DrizzleRowByIndex for turso::Row {
743 fn get_column<T: FromSQLiteValue>(&self, idx: usize) -> Result<T, DrizzleError> {
744 let value = self.get_value(idx)?;
745 if value.is_null() {
746 T::from_sqlite_null()
747 } else if let Some(&i) = value.as_integer() {
748 T::from_sqlite_integer(i)
749 } else if let Some(s) = value.as_text() {
750 T::from_sqlite_text(s)
751 } else if let Some(&r) = value.as_real() {
752 T::from_sqlite_real(r)
753 } else if let Some(b) = value.as_blob() {
754 T::from_sqlite_blob(b)
755 } else {
756 Err(DrizzleError::ConversionError(
757 "unknown SQLite value type".into(),
758 ))
759 }
760 }
761}
762
763#[cfg(feature = "uuid")]
768impl FromSQLiteValue for uuid::Uuid {
769 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
770 Err(DrizzleError::ConversionError(
771 "cannot convert INTEGER to UUID".into(),
772 ))
773 }
774
775 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
776 Self::parse_str(value).map_err(|e| {
777 DrizzleError::ConversionError(format!("invalid UUID string '{value}': {e}").into())
778 })
779 }
780
781 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
782 Err(DrizzleError::ConversionError(
783 "cannot convert REAL to UUID".into(),
784 ))
785 }
786
787 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
788 Self::from_slice(value)
789 .map_err(|e| DrizzleError::ConversionError(format!("invalid UUID bytes: {e}").into()))
790 }
791}
792
793#[cfg(feature = "chrono")]
798impl FromSQLiteValue for chrono::NaiveDate {
799 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
800 Err(DrizzleError::ConversionError(
801 "cannot convert INTEGER to NaiveDate".into(),
802 ))
803 }
804
805 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
806 value.parse().map_err(|e| {
807 DrizzleError::ConversionError(
808 format!("cannot parse '{value}' as NaiveDate: {e}").into(),
809 )
810 })
811 }
812
813 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
814 Err(DrizzleError::ConversionError(
815 "cannot convert REAL to NaiveDate".into(),
816 ))
817 }
818
819 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
820 Err(DrizzleError::ConversionError(
821 "cannot convert BLOB to NaiveDate".into(),
822 ))
823 }
824}
825
826#[cfg(feature = "chrono")]
827impl FromSQLiteValue for chrono::NaiveTime {
828 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
829 Err(DrizzleError::ConversionError(
830 "cannot convert INTEGER to NaiveTime".into(),
831 ))
832 }
833
834 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
835 value.parse().map_err(|e| {
836 DrizzleError::ConversionError(
837 format!("cannot parse '{value}' as NaiveTime: {e}").into(),
838 )
839 })
840 }
841
842 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
843 Err(DrizzleError::ConversionError(
844 "cannot convert REAL to NaiveTime".into(),
845 ))
846 }
847
848 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
849 Err(DrizzleError::ConversionError(
850 "cannot convert BLOB to NaiveTime".into(),
851 ))
852 }
853}
854
855#[cfg(feature = "chrono")]
856impl FromSQLiteValue for chrono::NaiveDateTime {
857 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
858 Err(DrizzleError::ConversionError(
859 "cannot convert INTEGER to NaiveDateTime".into(),
860 ))
861 }
862
863 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
864 value.parse().map_err(|e| {
865 DrizzleError::ConversionError(
866 format!("cannot parse '{value}' as NaiveDateTime: {e}").into(),
867 )
868 })
869 }
870
871 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
872 Err(DrizzleError::ConversionError(
873 "cannot convert REAL to NaiveDateTime".into(),
874 ))
875 }
876
877 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
878 Err(DrizzleError::ConversionError(
879 "cannot convert BLOB to NaiveDateTime".into(),
880 ))
881 }
882}
883
884#[cfg(feature = "chrono")]
885impl FromSQLiteValue for chrono::DateTime<chrono::FixedOffset> {
886 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
887 Err(DrizzleError::ConversionError(
888 "cannot convert INTEGER to DateTime<FixedOffset>".into(),
889 ))
890 }
891
892 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
893 Self::parse_from_rfc3339(value).map_err(|e| {
894 DrizzleError::ConversionError(
895 format!("cannot parse '{value}' as DateTime<FixedOffset>: {e}").into(),
896 )
897 })
898 }
899
900 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
901 Err(DrizzleError::ConversionError(
902 "cannot convert REAL to DateTime<FixedOffset>".into(),
903 ))
904 }
905
906 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
907 Err(DrizzleError::ConversionError(
908 "cannot convert BLOB to DateTime<FixedOffset>".into(),
909 ))
910 }
911}
912
913#[cfg(feature = "chrono")]
914impl FromSQLiteValue for chrono::DateTime<chrono::Utc> {
915 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
916 Err(DrizzleError::ConversionError(
917 "cannot convert INTEGER to DateTime<Utc>".into(),
918 ))
919 }
920
921 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
922 value.parse().map_err(|e| {
923 DrizzleError::ConversionError(
924 format!("cannot parse '{value}' as DateTime<Utc>: {e}").into(),
925 )
926 })
927 }
928
929 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
930 Err(DrizzleError::ConversionError(
931 "cannot convert REAL to DateTime<Utc>".into(),
932 ))
933 }
934
935 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
936 Err(DrizzleError::ConversionError(
937 "cannot convert BLOB to DateTime<Utc>".into(),
938 ))
939 }
940}
941
942#[cfg(feature = "time")]
947impl FromSQLiteValue for time::Date {
948 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
949 Err(DrizzleError::ConversionError(
950 "cannot convert INTEGER to time::Date".into(),
951 ))
952 }
953
954 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
955 Self::parse(value, &time::format_description::well_known::Iso8601::DATE).map_err(|e| {
956 DrizzleError::ConversionError(
957 format!("cannot parse '{value}' as time::Date: {e}").into(),
958 )
959 })
960 }
961
962 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
963 Err(DrizzleError::ConversionError(
964 "cannot convert REAL to time::Date".into(),
965 ))
966 }
967
968 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
969 Err(DrizzleError::ConversionError(
970 "cannot convert BLOB to time::Date".into(),
971 ))
972 }
973}
974
975#[cfg(feature = "time")]
976impl FromSQLiteValue for time::Time {
977 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
978 Err(DrizzleError::ConversionError(
979 "cannot convert INTEGER to time::Time".into(),
980 ))
981 }
982
983 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
984 Self::parse(value, &time::format_description::well_known::Iso8601::TIME).map_err(|e| {
985 DrizzleError::ConversionError(
986 format!("cannot parse '{value}' as time::Time: {e}").into(),
987 )
988 })
989 }
990
991 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
992 Err(DrizzleError::ConversionError(
993 "cannot convert REAL to time::Time".into(),
994 ))
995 }
996
997 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
998 Err(DrizzleError::ConversionError(
999 "cannot convert BLOB to time::Time".into(),
1000 ))
1001 }
1002}
1003
1004#[cfg(feature = "time")]
1005impl FromSQLiteValue for time::PrimitiveDateTime {
1006 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1007 Err(DrizzleError::ConversionError(
1008 "cannot convert INTEGER to time::PrimitiveDateTime".into(),
1009 ))
1010 }
1011
1012 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1013 Self::parse(
1014 value,
1015 &time::format_description::well_known::Iso8601::DATE_TIME,
1016 )
1017 .map_err(|e| {
1018 DrizzleError::ConversionError(
1019 format!("cannot parse '{value}' as time::PrimitiveDateTime: {e}").into(),
1020 )
1021 })
1022 }
1023
1024 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1025 Err(DrizzleError::ConversionError(
1026 "cannot convert REAL to time::PrimitiveDateTime".into(),
1027 ))
1028 }
1029
1030 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1031 Err(DrizzleError::ConversionError(
1032 "cannot convert BLOB to time::PrimitiveDateTime".into(),
1033 ))
1034 }
1035}
1036
1037#[cfg(feature = "time")]
1038impl FromSQLiteValue for time::OffsetDateTime {
1039 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1040 Err(DrizzleError::ConversionError(
1041 "cannot convert INTEGER to time::OffsetDateTime".into(),
1042 ))
1043 }
1044
1045 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1046 Self::parse(value, &time::format_description::well_known::Rfc3339).map_err(|e| {
1047 DrizzleError::ConversionError(
1048 format!("cannot parse '{value}' as time::OffsetDateTime: {e}").into(),
1049 )
1050 })
1051 }
1052
1053 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1054 Err(DrizzleError::ConversionError(
1055 "cannot convert REAL to time::OffsetDateTime".into(),
1056 ))
1057 }
1058
1059 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1060 Err(DrizzleError::ConversionError(
1061 "cannot convert BLOB to time::OffsetDateTime".into(),
1062 ))
1063 }
1064}
1065
1066#[cfg(feature = "rust-decimal")]
1071impl FromSQLiteValue for rust_decimal::Decimal {
1072 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
1073 Ok(Self::from(value))
1074 }
1075
1076 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1077 value.parse().map_err(|e| {
1078 DrizzleError::ConversionError(format!("cannot parse '{value}' as Decimal: {e}").into())
1079 })
1080 }
1081
1082 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
1083 Self::try_from(value).map_err(|e| {
1084 DrizzleError::ConversionError(
1085 format!("cannot convert REAL {value} to Decimal: {e}").into(),
1086 )
1087 })
1088 }
1089
1090 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1091 Err(DrizzleError::ConversionError(
1092 "cannot convert BLOB to Decimal".into(),
1093 ))
1094 }
1095}
1096
1097#[cfg(feature = "chrono")]
1102impl FromSQLiteValue for chrono::Duration {
1103 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
1104 Ok(Self::seconds(value))
1105 }
1106
1107 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1108 let secs: i64 = value.trim_end_matches('s').parse().map_err(|e| {
1110 DrizzleError::ConversionError(
1111 format!("cannot parse '{value}' as chrono::Duration: {e}").into(),
1112 )
1113 })?;
1114 Ok(Self::seconds(secs))
1115 }
1116
1117 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
1118 let millis: i64 = format!("{:.0}", value * 1000.0).parse().map_err(|e| {
1119 DrizzleError::ConversionError(
1120 format!("cannot convert REAL {value} to chrono::Duration: {e}").into(),
1121 )
1122 })?;
1123 Ok(Self::milliseconds(millis))
1124 }
1125
1126 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1127 Err(DrizzleError::ConversionError(
1128 "cannot convert BLOB to chrono::Duration".into(),
1129 ))
1130 }
1131}
1132
1133#[cfg(feature = "time")]
1134impl FromSQLiteValue for time::Duration {
1135 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
1136 Ok(Self::seconds(value))
1137 }
1138
1139 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1140 let secs: i64 = value.trim_end_matches('s').parse().map_err(|e| {
1142 DrizzleError::ConversionError(
1143 format!("cannot parse '{value}' as time::Duration: {e}").into(),
1144 )
1145 })?;
1146 Ok(Self::seconds(secs))
1147 }
1148
1149 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
1150 Ok(Self::seconds_f64(value))
1151 }
1152
1153 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1154 Err(DrizzleError::ConversionError(
1155 "cannot convert BLOB to time::Duration".into(),
1156 ))
1157 }
1158}
1159
1160#[cfg(feature = "serde")]
1165impl FromSQLiteValue for serde_json::Value {
1166 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
1167 Ok(Self::Number(value.into()))
1168 }
1169
1170 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1171 serde_json::from_str(value).map_err(|e| {
1172 DrizzleError::ConversionError(format!("cannot parse '{value}' as JSON: {e}").into())
1173 })
1174 }
1175
1176 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
1177 serde_json::Number::from_f64(value)
1178 .map(serde_json::Value::Number)
1179 .ok_or_else(|| {
1180 DrizzleError::ConversionError(
1181 format!("cannot convert non-finite REAL {value} to JSON").into(),
1182 )
1183 })
1184 }
1185
1186 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
1187 serde_json::from_slice(value).map_err(|e| {
1188 DrizzleError::ConversionError(format!("cannot parse BLOB as JSON: {e}").into())
1189 })
1190 }
1191}
1192
1193#[cfg(feature = "arrayvec")]
1198impl<const N: usize> FromSQLiteValue for arrayvec::ArrayString<N> {
1199 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
1200 let s = value.to_string();
1201 Self::from(&s).map_err(|_| {
1202 DrizzleError::ConversionError(
1203 format!(
1204 "String length {} exceeds ArrayString capacity {}",
1205 s.len(),
1206 N
1207 )
1208 .into(),
1209 )
1210 })
1211 }
1212
1213 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1214 Self::from(value).map_err(|_| {
1215 DrizzleError::ConversionError(
1216 format!(
1217 "Text length {} exceeds ArrayString capacity {}",
1218 value.len(),
1219 N
1220 )
1221 .into(),
1222 )
1223 })
1224 }
1225
1226 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
1227 let s = value.to_string();
1228 Self::from(&s).map_err(|_| {
1229 DrizzleError::ConversionError(
1230 format!(
1231 "String length {} exceeds ArrayString capacity {}",
1232 s.len(),
1233 N
1234 )
1235 .into(),
1236 )
1237 })
1238 }
1239
1240 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
1241 let s = String::from_utf8(value.to_vec())
1242 .map_err(|e| DrizzleError::ConversionError(format!("invalid UTF-8: {e}").into()))?;
1243 Self::from(&s).map_err(|_| {
1244 DrizzleError::ConversionError(
1245 format!(
1246 "String length {} exceeds ArrayString capacity {}",
1247 s.len(),
1248 N
1249 )
1250 .into(),
1251 )
1252 })
1253 }
1254}
1255
1256#[cfg(feature = "arrayvec")]
1257impl<const N: usize> FromSQLiteValue for arrayvec::ArrayVec<u8, N> {
1258 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1259 Err(DrizzleError::ConversionError(
1260 "cannot convert INTEGER to ArrayVec<u8>, use BLOB".into(),
1261 ))
1262 }
1263
1264 fn from_sqlite_text(_value: &str) -> Result<Self, DrizzleError> {
1265 Err(DrizzleError::ConversionError(
1266 "cannot convert TEXT to ArrayVec<u8>, use BLOB".into(),
1267 ))
1268 }
1269
1270 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1271 Err(DrizzleError::ConversionError(
1272 "cannot convert REAL to ArrayVec<u8>, use BLOB".into(),
1273 ))
1274 }
1275
1276 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
1277 Self::try_from(value).map_err(|_| {
1278 DrizzleError::ConversionError(
1279 format!(
1280 "Blob length {} exceeds ArrayVec capacity {}",
1281 value.len(),
1282 N
1283 )
1284 .into(),
1285 )
1286 })
1287 }
1288}