1use crate::prelude::*;
11use crate::values::{OwnedSQLiteValue, SQLiteValue, SQLiteValueRef};
12use drizzle_core::conv::checked_float_to_int;
13use drizzle_core::error::DrizzleError;
14
15pub trait SQLiteAffinity: drizzle_core::types::DataType {
18 const SQL_TYPE: &'static str;
20}
21
22macro_rules! impl_sqlite_affinity {
23 ($($marker:ty => $sql_type:literal),+ $(,)?) => {
24 $(
25 impl SQLiteAffinity for $marker {
26 const SQL_TYPE: &'static str = $sql_type;
27 }
28 )+
29 };
30}
31
32impl_sqlite_affinity! {
33 crate::types::Integer => "INTEGER",
34 crate::types::Text => "TEXT",
35 crate::types::Blob => "BLOB",
36 crate::types::Real => "REAL",
37 crate::types::Numeric => "NUMERIC",
38 crate::types::Any => "ANY",
39}
40
41#[diagnostic::on_unimplemented(
95 message = "`{Self}` cannot be used as a SQLite column type",
96 note = "add #[derive(SQLiteEnum)] for enum types, or use a supported primitive type"
97)]
98pub trait DrizzleSQLiteColumn: Sized {
99 type SQLType: SQLiteAffinity;
105
106 const SQL_TYPE: &'static str = <Self::SQLType as SQLiteAffinity>::SQL_TYPE;
113
114 fn decode(value: SQLiteValueRef<'_>) -> Result<Self, DrizzleError>;
124
125 fn encode(&self) -> SQLiteValue<'_>;
128
129 fn encode_owned(self) -> OwnedSQLiteValue {
135 self.encode().into_owned()
136 }
137
138 #[cfg(feature = "query")]
149 fn decode_json(value: &serde_json::Value) -> Result<Self, DrizzleError> {
150 let value = decode_projected_sqlite_value(value)?;
151 let value = value.as_value();
152 Self::decode(value.as_ref())
153 }
154}
155
156#[cfg(feature = "query")]
182pub fn decode_projected_sqlite_value(
183 value: &serde_json::Value,
184) -> Result<OwnedSQLiteValue, DrizzleError> {
185 if value.is_null() {
186 return Ok(OwnedSQLiteValue::Null);
187 }
188
189 let object = value.as_object().ok_or_else(|| {
190 DrizzleError::ConversionError("SQLite query value is missing its storage tag".into())
191 })?;
192 let storage = object
193 .get("$drizzle_storage")
194 .and_then(serde_json::Value::as_str)
195 .ok_or_else(|| {
196 DrizzleError::ConversionError("SQLite query value has no valid $drizzle_storage".into())
197 })?;
198 let value = object.get("$drizzle_value").ok_or_else(|| {
199 DrizzleError::ConversionError("SQLite query value has no $drizzle_value".into())
200 })?;
201
202 match storage {
203 "integer" => value
204 .as_i64()
205 .map(OwnedSQLiteValue::Integer)
206 .ok_or_else(|| {
207 DrizzleError::ConversionError(
208 "SQLite INTEGER query value is not a JSON integer".into(),
209 )
210 }),
211 "real" => value.as_f64().map(OwnedSQLiteValue::Real).ok_or_else(|| {
212 DrizzleError::ConversionError("SQLite REAL query value is not a JSON number".into())
213 }),
214 "text" => value
215 .as_str()
216 .map(|value| OwnedSQLiteValue::Text(value.to_owned()))
217 .ok_or_else(|| {
218 DrizzleError::ConversionError("SQLite TEXT query value is not a JSON string".into())
219 }),
220 "blob" => value
221 .as_str()
222 .ok_or_else(|| {
223 DrizzleError::ConversionError("SQLite BLOB query value is not a hex string".into())
224 })
225 .and_then(decode_projected_blob)
226 .map(|value| OwnedSQLiteValue::Blob(value.into_boxed_slice())),
227 other => Err(DrizzleError::ConversionError(
228 format!("unknown SQLite query storage class `{other}`").into(),
229 )),
230 }
231}
232
233#[cfg(feature = "query")]
234fn decode_projected_blob(value: &str) -> Result<Vec<u8>, DrizzleError> {
235 let (chunks, remainder) = value.as_bytes().as_chunks::<2>();
236 let mut bytes = Vec::with_capacity(value.len() / 2);
237 for chunk in chunks {
238 let high = decode_hex_nibble(chunk[0])?;
239 let low = decode_hex_nibble(chunk[1])?;
240 bytes.push((high << 4) | low);
241 }
242 if !remainder.is_empty() {
243 return Err(DrizzleError::ConversionError(
244 "hex-encoded SQLite BLOB has odd length".into(),
245 ));
246 }
247 Ok(bytes)
248}
249
250#[cfg(feature = "query")]
251fn decode_hex_nibble(value: u8) -> Result<u8, DrizzleError> {
252 match value {
253 b'0'..=b'9' => Ok(value - b'0'),
254 b'a'..=b'f' => Ok(value - b'a' + 10),
255 b'A'..=b'F' => Ok(value - b'A' + 10),
256 _ => Err(DrizzleError::ConversionError(
257 "SQLite BLOB query value contains a non-hex byte".into(),
258 )),
259 }
260}
261
262impl<'a, T> From<T> for SQLiteValue<'a>
263where
264 T: DrizzleSQLiteColumn,
265{
266 fn from(value: T) -> Self {
267 value.encode_owned().into()
268 }
269}
270
271pub trait FromSQLiteValue: Sized {
283 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError>;
289
290 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError>;
296
297 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError>;
303
304 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError>;
310
311 fn from_sqlite_ref(value: SQLiteValueRef<'_>) -> Result<Self, DrizzleError> {
319 match value {
320 SQLiteValueRef::Integer(value) => Self::from_sqlite_integer(value),
321 SQLiteValueRef::Text(value) => Self::from_sqlite_text(value),
322 SQLiteValueRef::Real(value) => Self::from_sqlite_real(value),
323 SQLiteValueRef::Blob(value) => Self::from_sqlite_blob(value),
324 SQLiteValueRef::Null => Self::from_sqlite_null(),
325 }
326 }
327
328 fn from_sqlite_null() -> Result<Self, DrizzleError> {
335 Err(DrizzleError::ConversionError(
336 "unexpected NULL value".into(),
337 ))
338 }
339
340 #[cfg(feature = "rusqlite")]
347 fn from_value_ref(value: ::rusqlite::types::ValueRef<'_>) -> Result<Self, DrizzleError> {
348 let value = SQLiteValueRef::try_from_rusqlite_value_ref(value)?;
349 Self::from_sqlite_ref(value)
350 }
351}
352
353impl<T> FromSQLiteValue for T
354where
355 T: DrizzleSQLiteColumn,
356{
357 fn from_sqlite_ref(value: SQLiteValueRef<'_>) -> Result<Self, DrizzleError> {
358 T::decode(value)
359 }
360
361 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
362 T::decode(SQLiteValueRef::Integer(value))
363 }
364
365 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
366 T::decode(SQLiteValueRef::Text(value))
367 }
368
369 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
370 T::decode(SQLiteValueRef::Real(value))
371 }
372
373 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
374 T::decode(SQLiteValueRef::Blob(value))
375 }
376
377 fn from_sqlite_null() -> Result<Self, DrizzleError> {
378 T::decode(SQLiteValueRef::Null)
379 }
380}
381
382pub trait DrizzleRowByIndex {
387 fn get_column<T: FromSQLiteValue>(&self, idx: usize) -> Result<T, DrizzleError>;
394}
395
396pub trait DrizzleRowByName: DrizzleRowByIndex {
401 fn get_column_by_name<T: FromSQLiteValue>(&self, name: &str) -> Result<T, DrizzleError>;
408}
409
410macro_rules! impl_from_sqlite_value_int {
416 (i64) => {
418 impl FromSQLiteValue for i64 {
419 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
420 Ok(value)
421 }
422
423 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
424 value.parse().map_err(|e| {
425 DrizzleError::ConversionError(format!("cannot parse '{}' as i64: {}", value, e).into())
426 })
427 }
428
429 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
430 checked_float_to_int(value, "i64")
431 }
432
433 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
434 Err(DrizzleError::ConversionError("cannot convert BLOB to i64".into()))
435 }
436 }
437 };
438 (unsigned64: $($ty:ty),+ $(,)?) => {
442 $(
443 impl FromSQLiteValue for $ty {
444 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
445 unsigned_from_stored_bits(value, stringify!($ty))
446 }
447
448 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
449 value.parse().map_err(|e| {
450 DrizzleError::ConversionError(
451 format!("cannot parse '{}' as {}: {}", value, stringify!($ty), e).into()
452 )
453 })
454 }
455
456 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
457 checked_float_to_int(value, stringify!($ty))
458 }
459
460 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
461 Err(DrizzleError::ConversionError(
462 concat!("cannot convert BLOB to ", stringify!($ty)).into()
463 ))
464 }
465 }
466 )+
467 };
468 ($($ty:ty),+ $(,)?) => {
470 $(
471 impl FromSQLiteValue for $ty {
472 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
473 value.try_into().map_err(|e| {
474 DrizzleError::ConversionError(
475 format!("i64 {} out of range for {}: {}", value, stringify!($ty), e).into(),
476 )
477 })
478 }
479
480 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
481 value.parse().map_err(|e| {
482 DrizzleError::ConversionError(
483 format!("cannot parse '{}' as {}: {}", value, stringify!($ty), e).into()
484 )
485 })
486 }
487
488 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
489 checked_float_to_int(value, stringify!($ty))
490 }
491
492 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
493 Err(DrizzleError::ConversionError(
494 concat!("cannot convert BLOB to ", stringify!($ty)).into()
495 ))
496 }
497 }
498 )+
499 };
500}
501
502fn unsigned_from_stored_bits<T>(value: i64, name: &str) -> Result<T, DrizzleError>
505where
506 T: TryFrom<u64>,
507 T::Error: core::fmt::Display,
508{
509 T::try_from(value.cast_unsigned()).map_err(|e| {
510 DrizzleError::ConversionError(format!("i64 {value} out of range for {name}: {e}").into())
511 })
512}
513
514#[inline]
517fn i64_to_f64(i: i64) -> f64 {
518 let high = i32::try_from(i >> 32).expect("sign-extended high word fits in i32");
519 let low = u32::try_from(i & 0xFFFF_FFFF).expect("masked low word fits in u32");
520 f64::from(high) * 4_294_967_296.0_f64 + f64::from(low)
521}
522
523impl_from_sqlite_value_int!(i64);
525impl_from_sqlite_value_int!(i8, i16, i32, isize, u8, u16, u32);
526impl_from_sqlite_value_int!(unsigned64: u64, usize);
527
528impl FromSQLiteValue for f64 {
531 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
532 Ok(i64_to_f64(value))
533 }
534
535 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
536 value.parse().map_err(|e| {
537 DrizzleError::ConversionError(format!("cannot parse '{value}' as f64: {e}").into())
538 })
539 }
540
541 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
542 Ok(value)
543 }
544
545 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
546 Err(DrizzleError::ConversionError(
547 "cannot convert BLOB to f64".into(),
548 ))
549 }
550}
551
552fn narrow_to_f32(value: f64) -> Result<f32, DrizzleError> {
553 format!("{value}").parse::<f32>().map_err(|e| {
557 DrizzleError::ConversionError(format!("cannot convert REAL {value} to f32: {e}").into())
558 })
559}
560
561impl FromSQLiteValue for f32 {
565 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
566 narrow_to_f32(i64_to_f64(value))
568 }
569
570 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
571 value.parse().map_err(|e| {
572 DrizzleError::ConversionError(format!("cannot parse '{value}' as f32: {e}").into())
573 })
574 }
575
576 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
577 narrow_to_f32(value)
578 }
579
580 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
581 Err(DrizzleError::ConversionError(
582 "cannot convert BLOB to f32".into(),
583 ))
584 }
585}
586
587impl FromSQLiteValue for bool {
588 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
589 Ok(value != 0)
590 }
591
592 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
593 match value.to_lowercase().as_str() {
594 "true" | "1" | "yes" | "on" => Ok(true),
595 "false" | "0" | "no" | "off" => Ok(false),
596 _ => Err(DrizzleError::ConversionError(
597 format!("cannot parse '{value}' as bool").into(),
598 )),
599 }
600 }
601
602 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
603 Ok(value != 0.0)
604 }
605
606 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
607 Err(DrizzleError::ConversionError(
608 "cannot convert BLOB to bool".into(),
609 ))
610 }
611}
612
613impl FromSQLiteValue for String {
614 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
615 Ok(value.to_string())
616 }
617
618 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
619 Ok(value.to_string())
620 }
621
622 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
623 Ok(value.to_string())
624 }
625
626 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
627 Self::from_utf8(value.to_vec()).map_err(|e| {
628 DrizzleError::ConversionError(format!("invalid UTF-8 in BLOB: {e}").into())
629 })
630 }
631}
632
633impl FromSQLiteValue for compact_str::CompactString {
634 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
635 Ok(Self::new(value.to_string()))
636 }
637
638 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
639 Ok(Self::new(value))
640 }
641
642 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
643 Ok(Self::new(value.to_string()))
644 }
645
646 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
647 let s = String::from_utf8(value.to_vec()).map_err(|e| {
648 DrizzleError::ConversionError(format!("invalid UTF-8 in BLOB: {e}").into())
649 })?;
650 Ok(Self::new(s))
651 }
652}
653
654impl FromSQLiteValue for Box<String> {
655 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
656 String::from_sqlite_integer(value).map(Self::new)
657 }
658
659 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
660 String::from_sqlite_text(value).map(Self::new)
661 }
662
663 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
664 String::from_sqlite_real(value).map(Self::new)
665 }
666
667 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
668 String::from_sqlite_blob(value).map(Self::new)
669 }
670}
671
672impl FromSQLiteValue for Rc<String> {
673 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
674 String::from_sqlite_integer(value).map(Self::new)
675 }
676
677 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
678 String::from_sqlite_text(value).map(Self::new)
679 }
680
681 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
682 String::from_sqlite_real(value).map(Self::new)
683 }
684
685 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
686 String::from_sqlite_blob(value).map(Self::new)
687 }
688}
689
690impl FromSQLiteValue for Arc<String> {
691 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
692 String::from_sqlite_integer(value).map(Self::new)
693 }
694
695 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
696 String::from_sqlite_text(value).map(Self::new)
697 }
698
699 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
700 String::from_sqlite_real(value).map(Self::new)
701 }
702
703 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
704 String::from_sqlite_blob(value).map(Self::new)
705 }
706}
707
708impl FromSQLiteValue for Box<str> {
709 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
710 String::from_sqlite_integer(value).map(String::into_boxed_str)
711 }
712
713 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
714 String::from_sqlite_text(value).map(String::into_boxed_str)
715 }
716
717 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
718 String::from_sqlite_real(value).map(String::into_boxed_str)
719 }
720
721 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
722 String::from_sqlite_blob(value).map(String::into_boxed_str)
723 }
724}
725
726impl FromSQLiteValue for Rc<str> {
727 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
728 String::from_sqlite_integer(value).map(Self::from)
729 }
730
731 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
732 String::from_sqlite_text(value).map(Self::from)
733 }
734
735 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
736 String::from_sqlite_real(value).map(Self::from)
737 }
738
739 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
740 String::from_sqlite_blob(value).map(Self::from)
741 }
742}
743
744impl FromSQLiteValue for Arc<str> {
745 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
746 String::from_sqlite_integer(value).map(Self::from)
747 }
748
749 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
750 String::from_sqlite_text(value).map(Self::from)
751 }
752
753 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
754 String::from_sqlite_real(value).map(Self::from)
755 }
756
757 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
758 String::from_sqlite_blob(value).map(Self::from)
759 }
760}
761
762impl FromSQLiteValue for Vec<u8> {
763 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
764 Ok(value.to_le_bytes().to_vec())
765 }
766
767 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
768 Ok(value.as_bytes().to_vec())
769 }
770
771 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
772 Ok(value.to_le_bytes().to_vec())
773 }
774
775 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
776 Ok(value.to_vec())
777 }
778}
779
780#[cfg(feature = "bytes")]
781impl FromSQLiteValue for bytes::Bytes {
782 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
783 Vec::<u8>::from_sqlite_integer(value).map(Self::from)
784 }
785
786 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
787 Vec::<u8>::from_sqlite_text(value).map(Self::from)
788 }
789
790 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
791 Vec::<u8>::from_sqlite_real(value).map(Self::from)
792 }
793
794 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
795 Ok(Self::copy_from_slice(value))
796 }
797}
798
799#[cfg(feature = "bytes")]
800impl FromSQLiteValue for bytes::BytesMut {
801 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
802 Vec::<u8>::from_sqlite_integer(value).map(|v| Self::from(v.as_slice()))
803 }
804
805 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
806 Vec::<u8>::from_sqlite_text(value).map(|v| Self::from(v.as_slice()))
807 }
808
809 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
810 Vec::<u8>::from_sqlite_real(value).map(|v| Self::from(v.as_slice()))
811 }
812
813 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
814 Ok(Self::from(value))
815 }
816}
817
818#[cfg(feature = "smallvec")]
819impl<const N: usize> FromSQLiteValue for smallvec::SmallVec<[u8; N]> {
820 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
821 Err(DrizzleError::ConversionError(
822 "cannot convert INTEGER to SmallVec<u8>, use BLOB".into(),
823 ))
824 }
825
826 fn from_sqlite_text(_value: &str) -> Result<Self, DrizzleError> {
827 Err(DrizzleError::ConversionError(
828 "cannot convert TEXT to SmallVec<u8>, use BLOB".into(),
829 ))
830 }
831
832 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
833 Err(DrizzleError::ConversionError(
834 "cannot convert REAL to SmallVec<u8>, use BLOB".into(),
835 ))
836 }
837
838 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
839 let mut out = Self::new();
840 out.extend_from_slice(value);
841 Ok(out)
842 }
843}
844
845impl FromSQLiteValue for Box<Vec<u8>> {
846 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
847 Vec::<u8>::from_sqlite_integer(value).map(Self::new)
848 }
849
850 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
851 Vec::<u8>::from_sqlite_text(value).map(Self::new)
852 }
853
854 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
855 Vec::<u8>::from_sqlite_real(value).map(Self::new)
856 }
857
858 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
859 Vec::<u8>::from_sqlite_blob(value).map(Self::new)
860 }
861}
862
863impl FromSQLiteValue for Rc<Vec<u8>> {
864 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
865 Vec::<u8>::from_sqlite_integer(value).map(Self::new)
866 }
867
868 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
869 Vec::<u8>::from_sqlite_text(value).map(Self::new)
870 }
871
872 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
873 Vec::<u8>::from_sqlite_real(value).map(Self::new)
874 }
875
876 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
877 Vec::<u8>::from_sqlite_blob(value).map(Self::new)
878 }
879}
880
881impl FromSQLiteValue for Arc<Vec<u8>> {
882 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
883 Vec::<u8>::from_sqlite_integer(value).map(Self::new)
884 }
885
886 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
887 Vec::<u8>::from_sqlite_text(value).map(Self::new)
888 }
889
890 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
891 Vec::<u8>::from_sqlite_real(value).map(Self::new)
892 }
893
894 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
895 Vec::<u8>::from_sqlite_blob(value).map(Self::new)
896 }
897}
898
899impl<T: FromSQLiteValue> FromSQLiteValue for Option<T> {
901 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
902 T::from_sqlite_integer(value).map(Some)
903 }
904
905 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
906 T::from_sqlite_text(value).map(Some)
907 }
908
909 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
910 T::from_sqlite_real(value).map(Some)
911 }
912
913 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
914 T::from_sqlite_blob(value).map(Some)
915 }
916
917 fn from_sqlite_null() -> Result<Self, DrizzleError> {
918 Ok(None)
919 }
920}
921
922#[cfg(feature = "rusqlite")]
927impl DrizzleRowByIndex for rusqlite::Row<'_> {
928 fn get_column<T: FromSQLiteValue>(&self, idx: usize) -> Result<T, DrizzleError> {
929 let value_ref = self.get_ref(idx)?;
930 match value_ref {
931 rusqlite::types::ValueRef::Integer(i) => T::from_sqlite_integer(i),
932 rusqlite::types::ValueRef::Text(s) => {
933 let s = core::str::from_utf8(s).map_err(|e| {
934 DrizzleError::ConversionError(format!("invalid UTF-8: {e}").into())
935 })?;
936 T::from_sqlite_text(s)
937 }
938 rusqlite::types::ValueRef::Real(r) => T::from_sqlite_real(r),
939 rusqlite::types::ValueRef::Blob(b) => T::from_sqlite_blob(b),
940 rusqlite::types::ValueRef::Null => T::from_sqlite_null(),
941 }
942 }
943}
944
945#[cfg(feature = "rusqlite")]
946impl DrizzleRowByName for rusqlite::Row<'_> {
947 fn get_column_by_name<T: FromSQLiteValue>(&self, name: &str) -> Result<T, DrizzleError> {
948 let idx = self.as_ref().column_index(name)?;
949 DrizzleRowByIndex::get_column(self, idx)
950 }
951}
952
953#[cfg(feature = "libsql")]
954impl DrizzleRowByIndex for libsql::Row {
955 fn get_column<T: FromSQLiteValue>(&self, idx: usize) -> Result<T, DrizzleError> {
956 let idx_i32 = i32::try_from(idx).map_err(|e| {
957 DrizzleError::ConversionError(format!("column index {idx} out of range: {e}").into())
958 })?;
959 let value = self.get_value(idx_i32)?;
960 match value {
961 libsql::Value::Integer(i) => T::from_sqlite_integer(i),
962 libsql::Value::Text(ref s) => T::from_sqlite_text(s),
963 libsql::Value::Real(r) => T::from_sqlite_real(r),
964 libsql::Value::Blob(ref b) => T::from_sqlite_blob(b),
965 libsql::Value::Null => T::from_sqlite_null(),
966 }
967 }
968}
969
970#[cfg(feature = "libsql")]
971impl DrizzleRowByName for libsql::Row {
972 fn get_column_by_name<T: FromSQLiteValue>(&self, name: &str) -> Result<T, DrizzleError> {
973 let idx = (0..self.column_count())
974 .find(|&i| self.column_name(i) == Some(name))
975 .ok_or_else(|| {
976 DrizzleError::ConversionError(format!("column '{name}' not found").into())
977 })?;
978
979 let idx_usize = usize::try_from(idx).map_err(|e| {
980 DrizzleError::ConversionError(format!("column index {idx} negative: {e}").into())
981 })?;
982 DrizzleRowByIndex::get_column(self, idx_usize)
983 }
984}
985
986#[cfg(feature = "turso")]
987impl DrizzleRowByIndex for turso::Row {
988 fn get_column<T: FromSQLiteValue>(&self, idx: usize) -> Result<T, DrizzleError> {
989 let value = self.get_value(idx)?;
990 if value.is_null() {
991 T::from_sqlite_null()
992 } else if let Some(&i) = value.as_integer() {
993 T::from_sqlite_integer(i)
994 } else if let Some(s) = value.as_text() {
995 T::from_sqlite_text(s)
996 } else if let Some(&r) = value.as_real() {
997 T::from_sqlite_real(r)
998 } else if let Some(b) = value.as_blob() {
999 T::from_sqlite_blob(b)
1000 } else {
1001 Err(DrizzleError::ConversionError(
1002 "unknown SQLite value type".into(),
1003 ))
1004 }
1005 }
1006}
1007
1008#[cfg(feature = "uuid")]
1013impl FromSQLiteValue for uuid::Uuid {
1014 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1015 Err(DrizzleError::ConversionError(
1016 "cannot convert INTEGER to UUID".into(),
1017 ))
1018 }
1019
1020 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1021 Self::parse_str(value).map_err(|e| {
1022 DrizzleError::ConversionError(format!("invalid UUID string '{value}': {e}").into())
1023 })
1024 }
1025
1026 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1027 Err(DrizzleError::ConversionError(
1028 "cannot convert REAL to UUID".into(),
1029 ))
1030 }
1031
1032 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
1033 Self::from_slice(value)
1034 .map_err(|e| DrizzleError::ConversionError(format!("invalid UUID bytes: {e}").into()))
1035 }
1036}
1037
1038#[cfg(feature = "chrono")]
1043impl FromSQLiteValue for chrono::NaiveDate {
1044 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1045 Err(DrizzleError::ConversionError(
1046 "cannot convert INTEGER to NaiveDate".into(),
1047 ))
1048 }
1049
1050 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1051 value.parse().map_err(|e| {
1052 DrizzleError::ConversionError(
1053 format!("cannot parse '{value}' as NaiveDate: {e}").into(),
1054 )
1055 })
1056 }
1057
1058 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1059 Err(DrizzleError::ConversionError(
1060 "cannot convert REAL to NaiveDate".into(),
1061 ))
1062 }
1063
1064 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1065 Err(DrizzleError::ConversionError(
1066 "cannot convert BLOB to NaiveDate".into(),
1067 ))
1068 }
1069}
1070
1071#[cfg(feature = "chrono")]
1072impl FromSQLiteValue for chrono::NaiveTime {
1073 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1074 Err(DrizzleError::ConversionError(
1075 "cannot convert INTEGER to NaiveTime".into(),
1076 ))
1077 }
1078
1079 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1080 value.parse().map_err(|e| {
1081 DrizzleError::ConversionError(
1082 format!("cannot parse '{value}' as NaiveTime: {e}").into(),
1083 )
1084 })
1085 }
1086
1087 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1088 Err(DrizzleError::ConversionError(
1089 "cannot convert REAL to NaiveTime".into(),
1090 ))
1091 }
1092
1093 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1094 Err(DrizzleError::ConversionError(
1095 "cannot convert BLOB to NaiveTime".into(),
1096 ))
1097 }
1098}
1099
1100#[cfg(feature = "chrono")]
1101impl FromSQLiteValue for chrono::NaiveDateTime {
1102 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1103 Err(DrizzleError::ConversionError(
1104 "cannot convert INTEGER to NaiveDateTime".into(),
1105 ))
1106 }
1107
1108 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1109 chrono_text::naive(value).map_err(|e| {
1110 DrizzleError::ConversionError(
1111 format!("cannot parse '{value}' as NaiveDateTime: {e}").into(),
1112 )
1113 })
1114 }
1115
1116 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1117 Err(DrizzleError::ConversionError(
1118 "cannot convert REAL to NaiveDateTime".into(),
1119 ))
1120 }
1121
1122 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1123 Err(DrizzleError::ConversionError(
1124 "cannot convert BLOB to NaiveDateTime".into(),
1125 ))
1126 }
1127}
1128
1129#[cfg(feature = "chrono")]
1130impl FromSQLiteValue for chrono::DateTime<chrono::FixedOffset> {
1131 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1132 Err(DrizzleError::ConversionError(
1133 "cannot convert INTEGER to DateTime<FixedOffset>".into(),
1134 ))
1135 }
1136
1137 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1138 chrono_text::fixed(value).map_err(|e| {
1139 DrizzleError::ConversionError(
1140 format!("cannot parse '{value}' as DateTime<FixedOffset>: {e}").into(),
1141 )
1142 })
1143 }
1144
1145 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1146 Err(DrizzleError::ConversionError(
1147 "cannot convert REAL to DateTime<FixedOffset>".into(),
1148 ))
1149 }
1150
1151 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1152 Err(DrizzleError::ConversionError(
1153 "cannot convert BLOB to DateTime<FixedOffset>".into(),
1154 ))
1155 }
1156}
1157
1158#[cfg(feature = "chrono")]
1159impl FromSQLiteValue for chrono::DateTime<chrono::Utc> {
1160 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1161 Err(DrizzleError::ConversionError(
1162 "cannot convert INTEGER to DateTime<Utc>".into(),
1163 ))
1164 }
1165
1166 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1167 chrono_text::utc(value).map_err(|e| {
1168 DrizzleError::ConversionError(
1169 format!("cannot parse '{value}' as DateTime<Utc>: {e}").into(),
1170 )
1171 })
1172 }
1173
1174 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1175 Err(DrizzleError::ConversionError(
1176 "cannot convert REAL to DateTime<Utc>".into(),
1177 ))
1178 }
1179
1180 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1181 Err(DrizzleError::ConversionError(
1182 "cannot convert BLOB to DateTime<Utc>".into(),
1183 ))
1184 }
1185}
1186
1187#[cfg(feature = "chrono")]
1198pub(crate) mod chrono_text {
1199 use chrono::{DateTime, FixedOffset, NaiveDateTime, Offset, ParseResult, Utc};
1200
1201 pub(crate) fn naive(text: &str) -> ParseResult<NaiveDateTime> {
1203 NaiveDateTime::parse_from_str(text, "%Y-%m-%d %H:%M:%S%.f").or_else(|_| text.parse())
1204 }
1205
1206 pub(crate) fn fixed(text: &str) -> ParseResult<DateTime<FixedOffset>> {
1208 DateTime::parse_from_rfc3339(text).or_else(|error| {
1209 naive(text)
1210 .map(|value| DateTime::from_naive_utc_and_offset(value, Utc.fix()))
1211 .map_err(|_| error)
1212 })
1213 }
1214
1215 pub(crate) fn utc(text: &str) -> ParseResult<DateTime<Utc>> {
1217 text.parse().or_else(|error| {
1218 naive(text)
1219 .map(|value| DateTime::from_naive_utc_and_offset(value, Utc))
1220 .map_err(|_| error)
1221 })
1222 }
1223}
1224
1225#[cfg(feature = "time")]
1231pub(crate) mod time_text {
1232 use time::format_description::well_known::{Iso8601, Rfc3339};
1233 use time::macros::format_description;
1234
1235 pub(crate) fn time(text: &str) -> Result<time::Time, time::error::Parse> {
1238 let text = text.strip_prefix('T').unwrap_or(text);
1239 time::Time::parse(
1240 text,
1241 format_description!("[hour]:[minute]:[second].[subsecond]"),
1242 )
1243 .or_else(|_| time::Time::parse(text, format_description!("[hour]:[minute]:[second]")))
1244 }
1245
1246 pub(crate) fn primitive(text: &str) -> Result<time::PrimitiveDateTime, time::error::Parse> {
1248 time::PrimitiveDateTime::parse(text, &Iso8601::DATE_TIME)
1249 .or_else(|_| {
1250 time::PrimitiveDateTime::parse(
1251 text,
1252 format_description!(
1253 "[year]-[month]-[day] [hour]:[minute]:[second].[subsecond]"
1254 ),
1255 )
1256 })
1257 .or_else(|_| {
1258 time::PrimitiveDateTime::parse(
1259 text,
1260 format_description!("[year]-[month]-[day] [hour]:[minute]:[second]"),
1261 )
1262 })
1263 }
1264
1265 pub(crate) fn offset(text: &str) -> Result<time::OffsetDateTime, time::error::Parse> {
1267 time::OffsetDateTime::parse(text, &Rfc3339).or_else(|error| {
1268 primitive(text)
1269 .map(time::PrimitiveDateTime::assume_utc)
1270 .map_err(|_| error)
1271 })
1272 }
1273}
1274
1275#[cfg(feature = "time")]
1276impl FromSQLiteValue for time::Date {
1277 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1278 Err(DrizzleError::ConversionError(
1279 "cannot convert INTEGER to time::Date".into(),
1280 ))
1281 }
1282
1283 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1284 Self::parse(value, &time::format_description::well_known::Iso8601::DATE).map_err(|e| {
1285 DrizzleError::ConversionError(
1286 format!("cannot parse '{value}' as time::Date: {e}").into(),
1287 )
1288 })
1289 }
1290
1291 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1292 Err(DrizzleError::ConversionError(
1293 "cannot convert REAL to time::Date".into(),
1294 ))
1295 }
1296
1297 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1298 Err(DrizzleError::ConversionError(
1299 "cannot convert BLOB to time::Date".into(),
1300 ))
1301 }
1302}
1303
1304#[cfg(feature = "time")]
1305impl FromSQLiteValue for time::Time {
1306 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1307 Err(DrizzleError::ConversionError(
1308 "cannot convert INTEGER to time::Time".into(),
1309 ))
1310 }
1311
1312 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1313 time_text::time(value).map_err(|e| {
1314 DrizzleError::ConversionError(
1315 format!("cannot parse '{value}' as time::Time: {e}").into(),
1316 )
1317 })
1318 }
1319
1320 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1321 Err(DrizzleError::ConversionError(
1322 "cannot convert REAL to time::Time".into(),
1323 ))
1324 }
1325
1326 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1327 Err(DrizzleError::ConversionError(
1328 "cannot convert BLOB to time::Time".into(),
1329 ))
1330 }
1331}
1332
1333#[cfg(feature = "time")]
1334impl FromSQLiteValue for time::PrimitiveDateTime {
1335 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1336 Err(DrizzleError::ConversionError(
1337 "cannot convert INTEGER to time::PrimitiveDateTime".into(),
1338 ))
1339 }
1340
1341 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1342 time_text::primitive(value).map_err(|e| {
1343 DrizzleError::ConversionError(
1344 format!("cannot parse '{value}' as time::PrimitiveDateTime: {e}").into(),
1345 )
1346 })
1347 }
1348
1349 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1350 Err(DrizzleError::ConversionError(
1351 "cannot convert REAL to time::PrimitiveDateTime".into(),
1352 ))
1353 }
1354
1355 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1356 Err(DrizzleError::ConversionError(
1357 "cannot convert BLOB to time::PrimitiveDateTime".into(),
1358 ))
1359 }
1360}
1361
1362#[cfg(feature = "time")]
1363impl FromSQLiteValue for time::OffsetDateTime {
1364 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1365 Err(DrizzleError::ConversionError(
1366 "cannot convert INTEGER to time::OffsetDateTime".into(),
1367 ))
1368 }
1369
1370 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1371 time_text::offset(value).map_err(|e| {
1372 DrizzleError::ConversionError(
1373 format!("cannot parse '{value}' as time::OffsetDateTime: {e}").into(),
1374 )
1375 })
1376 }
1377
1378 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1379 Err(DrizzleError::ConversionError(
1380 "cannot convert REAL to time::OffsetDateTime".into(),
1381 ))
1382 }
1383
1384 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1385 Err(DrizzleError::ConversionError(
1386 "cannot convert BLOB to time::OffsetDateTime".into(),
1387 ))
1388 }
1389}
1390
1391#[cfg(feature = "jiff")]
1397fn parse_jiff<T: core::str::FromStr<Err = jiff::Error>>(
1398 value: &str,
1399 name: &str,
1400) -> Result<T, DrizzleError> {
1401 value.parse().map_err(|e: jiff::Error| {
1402 DrizzleError::ConversionError(format!("cannot parse '{value}' as {name}: {e}").into())
1403 })
1404}
1405
1406#[cfg(feature = "jiff")]
1408macro_rules! impl_from_sqlite_value_jiff {
1409 ($($ty:ty => $name:literal, $parse:expr;)+) => {$(
1410 impl FromSQLiteValue for $ty {
1411 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1412 Err(DrizzleError::ConversionError(
1413 concat!("cannot convert INTEGER to ", $name).into(),
1414 ))
1415 }
1416
1417 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1418 $parse(value)
1419 }
1420
1421 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1422 Err(DrizzleError::ConversionError(
1423 concat!("cannot convert REAL to ", $name).into(),
1424 ))
1425 }
1426
1427 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1428 Err(DrizzleError::ConversionError(
1429 concat!("cannot convert BLOB to ", $name).into(),
1430 ))
1431 }
1432 }
1433 )+};
1434}
1435
1436#[cfg(feature = "jiff")]
1437impl_from_sqlite_value_jiff! {
1438 jiff::civil::Date => "jiff::civil::Date",
1439 |value| parse_jiff(value, "jiff::civil::Date");
1440 jiff::civil::Time => "jiff::civil::Time",
1441 |value| parse_jiff(value, "jiff::civil::Time");
1442 jiff::civil::DateTime => "jiff::civil::DateTime",
1443 |value| parse_jiff(value, "jiff::civil::DateTime");
1444 jiff::Timestamp => "jiff::Timestamp", |value: &str| {
1447 value.parse().or_else(|_| {
1448 let civil: jiff::civil::DateTime = parse_jiff(value, "jiff::Timestamp")?;
1449 jiff::tz::Offset::UTC.to_timestamp(civil).map_err(|e| {
1450 DrizzleError::ConversionError(
1451 format!("cannot convert '{value}' to jiff::Timestamp: {e}").into(),
1452 )
1453 })
1454 })
1455 };
1456}
1457
1458#[cfg(feature = "rust-decimal")]
1463impl FromSQLiteValue for rust_decimal::Decimal {
1464 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
1465 Ok(Self::from(value))
1466 }
1467
1468 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1469 value.parse().map_err(|e| {
1470 DrizzleError::ConversionError(format!("cannot parse '{value}' as Decimal: {e}").into())
1471 })
1472 }
1473
1474 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
1475 Self::try_from(value).map_err(|e| {
1476 DrizzleError::ConversionError(
1477 format!("cannot convert REAL {value} to Decimal: {e}").into(),
1478 )
1479 })
1480 }
1481
1482 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1483 Err(DrizzleError::ConversionError(
1484 "cannot convert BLOB to Decimal".into(),
1485 ))
1486 }
1487}
1488
1489#[cfg(feature = "chrono")]
1494impl FromSQLiteValue for chrono::Duration {
1495 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
1496 Ok(Self::seconds(value))
1497 }
1498
1499 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1500 let error = || {
1501 DrizzleError::ConversionError(
1502 format!("cannot parse '{value}' as chrono::Duration").into(),
1503 )
1504 };
1505 let (negative, secs, nanos) = crate::values::duration::parse(value).ok_or_else(error)?;
1506 let secs = i64::try_from(secs).map_err(|_| error())?;
1507 let duration = Self::new(secs, nanos).ok_or_else(error)?;
1508 Ok(if negative { -duration } else { duration })
1509 }
1510
1511 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
1512 let millis: i64 = format!("{:.0}", value * 1000.0).parse().map_err(|e| {
1513 DrizzleError::ConversionError(
1514 format!("cannot convert REAL {value} to chrono::Duration: {e}").into(),
1515 )
1516 })?;
1517 Ok(Self::milliseconds(millis))
1518 }
1519
1520 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1521 Err(DrizzleError::ConversionError(
1522 "cannot convert BLOB to chrono::Duration".into(),
1523 ))
1524 }
1525}
1526
1527#[cfg(feature = "time")]
1528impl FromSQLiteValue for time::Duration {
1529 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
1530 Ok(Self::seconds(value))
1531 }
1532
1533 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1534 let error = || {
1535 DrizzleError::ConversionError(
1536 format!("cannot parse '{value}' as time::Duration").into(),
1537 )
1538 };
1539 let (negative, secs, nanos) = crate::values::duration::parse(value).ok_or_else(error)?;
1540 let secs = i64::try_from(secs).map_err(|_| error())?;
1541 let duration = Self::new(secs, nanos as i32);
1543 Ok(if negative { -duration } else { duration })
1544 }
1545
1546 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
1547 Ok(Self::seconds_f64(value))
1548 }
1549
1550 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1551 Err(DrizzleError::ConversionError(
1552 "cannot convert BLOB to time::Duration".into(),
1553 ))
1554 }
1555}
1556
1557#[cfg(feature = "serde")]
1562impl FromSQLiteValue for serde_json::Value {
1563 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
1564 Ok(Self::Number(value.into()))
1565 }
1566
1567 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1568 serde_json::from_str(value).map_err(|e| {
1569 DrizzleError::ConversionError(format!("cannot parse '{value}' as JSON: {e}").into())
1570 })
1571 }
1572
1573 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
1574 serde_json::Number::from_f64(value)
1575 .map(serde_json::Value::Number)
1576 .ok_or_else(|| {
1577 DrizzleError::ConversionError(
1578 format!("cannot convert non-finite REAL {value} to JSON").into(),
1579 )
1580 })
1581 }
1582
1583 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
1584 serde_json::from_slice(value).map_err(|e| {
1585 DrizzleError::ConversionError(format!("cannot parse BLOB as JSON: {e}").into())
1586 })
1587 }
1588}
1589
1590#[cfg(feature = "arrayvec")]
1595impl<const N: usize> FromSQLiteValue for arrayvec::ArrayString<N> {
1596 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
1597 let s = value.to_string();
1598 Self::from(&s).map_err(|_| {
1599 DrizzleError::ConversionError(
1600 format!(
1601 "String length {} exceeds ArrayString capacity {}",
1602 s.len(),
1603 N
1604 )
1605 .into(),
1606 )
1607 })
1608 }
1609
1610 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1611 Self::from(value).map_err(|_| {
1612 DrizzleError::ConversionError(
1613 format!(
1614 "Text length {} exceeds ArrayString capacity {}",
1615 value.len(),
1616 N
1617 )
1618 .into(),
1619 )
1620 })
1621 }
1622
1623 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
1624 let s = value.to_string();
1625 Self::from(&s).map_err(|_| {
1626 DrizzleError::ConversionError(
1627 format!(
1628 "String length {} exceeds ArrayString capacity {}",
1629 s.len(),
1630 N
1631 )
1632 .into(),
1633 )
1634 })
1635 }
1636
1637 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
1638 let s = String::from_utf8(value.to_vec())
1639 .map_err(|e| DrizzleError::ConversionError(format!("invalid UTF-8: {e}").into()))?;
1640 Self::from(&s).map_err(|_| {
1641 DrizzleError::ConversionError(
1642 format!(
1643 "String length {} exceeds ArrayString capacity {}",
1644 s.len(),
1645 N
1646 )
1647 .into(),
1648 )
1649 })
1650 }
1651}
1652
1653#[cfg(feature = "arrayvec")]
1654impl<const N: usize> FromSQLiteValue for arrayvec::ArrayVec<u8, N> {
1655 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1656 Err(DrizzleError::ConversionError(
1657 "cannot convert INTEGER to ArrayVec<u8>, use BLOB".into(),
1658 ))
1659 }
1660
1661 fn from_sqlite_text(_value: &str) -> Result<Self, DrizzleError> {
1662 Err(DrizzleError::ConversionError(
1663 "cannot convert TEXT to ArrayVec<u8>, use BLOB".into(),
1664 ))
1665 }
1666
1667 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1668 Err(DrizzleError::ConversionError(
1669 "cannot convert REAL to ArrayVec<u8>, use BLOB".into(),
1670 ))
1671 }
1672
1673 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
1674 Self::try_from(value).map_err(|_| {
1675 DrizzleError::ConversionError(
1676 format!(
1677 "Blob length {} exceeds ArrayVec capacity {}",
1678 value.len(),
1679 N
1680 )
1681 .into(),
1682 )
1683 })
1684 }
1685}