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 ($($ty:ty),+ $(,)?) => {
440 $(
441 impl FromSQLiteValue for $ty {
442 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
443 value.try_into().map_err(|e| {
444 DrizzleError::ConversionError(
445 format!("i64 {} out of range for {}: {}", value, stringify!($ty), e).into(),
446 )
447 })
448 }
449
450 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
451 value.parse().map_err(|e| {
452 DrizzleError::ConversionError(
453 format!("cannot parse '{}' as {}: {}", value, stringify!($ty), e).into()
454 )
455 })
456 }
457
458 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
459 checked_float_to_int(value, stringify!($ty))
460 }
461
462 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
463 Err(DrizzleError::ConversionError(
464 concat!("cannot convert BLOB to ", stringify!($ty)).into()
465 ))
466 }
467 }
468 )+
469 };
470}
471
472#[inline]
475fn i64_to_f64(i: i64) -> f64 {
476 let high = i32::try_from(i >> 32).expect("sign-extended high word fits in i32");
477 let low = u32::try_from(i & 0xFFFF_FFFF).expect("masked low word fits in u32");
478 f64::from(high) * 4_294_967_296.0_f64 + f64::from(low)
479}
480
481impl_from_sqlite_value_int!(i64);
483impl_from_sqlite_value_int!(i8, i16, i32, isize, u8, u16, u32, u64, usize);
484
485impl FromSQLiteValue for f64 {
488 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
489 Ok(i64_to_f64(value))
490 }
491
492 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
493 value.parse().map_err(|e| {
494 DrizzleError::ConversionError(format!("cannot parse '{value}' as f64: {e}").into())
495 })
496 }
497
498 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
499 Ok(value)
500 }
501
502 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
503 Err(DrizzleError::ConversionError(
504 "cannot convert BLOB to f64".into(),
505 ))
506 }
507}
508
509fn narrow_to_f32(value: f64) -> Result<f32, DrizzleError> {
510 format!("{value}").parse::<f32>().map_err(|e| {
514 DrizzleError::ConversionError(format!("cannot convert REAL {value} to f32: {e}").into())
515 })
516}
517
518impl FromSQLiteValue for f32 {
522 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
523 narrow_to_f32(i64_to_f64(value))
525 }
526
527 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
528 value.parse().map_err(|e| {
529 DrizzleError::ConversionError(format!("cannot parse '{value}' as f32: {e}").into())
530 })
531 }
532
533 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
534 narrow_to_f32(value)
535 }
536
537 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
538 Err(DrizzleError::ConversionError(
539 "cannot convert BLOB to f32".into(),
540 ))
541 }
542}
543
544impl FromSQLiteValue for bool {
545 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
546 Ok(value != 0)
547 }
548
549 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
550 match value.to_lowercase().as_str() {
551 "true" | "1" | "yes" | "on" => Ok(true),
552 "false" | "0" | "no" | "off" => Ok(false),
553 _ => Err(DrizzleError::ConversionError(
554 format!("cannot parse '{value}' as bool").into(),
555 )),
556 }
557 }
558
559 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
560 Ok(value != 0.0)
561 }
562
563 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
564 Err(DrizzleError::ConversionError(
565 "cannot convert BLOB to bool".into(),
566 ))
567 }
568}
569
570impl FromSQLiteValue for String {
571 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
572 Ok(value.to_string())
573 }
574
575 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
576 Ok(value.to_string())
577 }
578
579 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
580 Ok(value.to_string())
581 }
582
583 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
584 Self::from_utf8(value.to_vec()).map_err(|e| {
585 DrizzleError::ConversionError(format!("invalid UTF-8 in BLOB: {e}").into())
586 })
587 }
588}
589
590impl FromSQLiteValue for compact_str::CompactString {
591 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
592 Ok(Self::new(value.to_string()))
593 }
594
595 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
596 Ok(Self::new(value))
597 }
598
599 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
600 Ok(Self::new(value.to_string()))
601 }
602
603 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
604 let s = String::from_utf8(value.to_vec()).map_err(|e| {
605 DrizzleError::ConversionError(format!("invalid UTF-8 in BLOB: {e}").into())
606 })?;
607 Ok(Self::new(s))
608 }
609}
610
611impl FromSQLiteValue for Box<String> {
612 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
613 String::from_sqlite_integer(value).map(Self::new)
614 }
615
616 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
617 String::from_sqlite_text(value).map(Self::new)
618 }
619
620 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
621 String::from_sqlite_real(value).map(Self::new)
622 }
623
624 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
625 String::from_sqlite_blob(value).map(Self::new)
626 }
627}
628
629impl FromSQLiteValue for Rc<String> {
630 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
631 String::from_sqlite_integer(value).map(Self::new)
632 }
633
634 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
635 String::from_sqlite_text(value).map(Self::new)
636 }
637
638 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
639 String::from_sqlite_real(value).map(Self::new)
640 }
641
642 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
643 String::from_sqlite_blob(value).map(Self::new)
644 }
645}
646
647impl FromSQLiteValue for Arc<String> {
648 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
649 String::from_sqlite_integer(value).map(Self::new)
650 }
651
652 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
653 String::from_sqlite_text(value).map(Self::new)
654 }
655
656 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
657 String::from_sqlite_real(value).map(Self::new)
658 }
659
660 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
661 String::from_sqlite_blob(value).map(Self::new)
662 }
663}
664
665impl FromSQLiteValue for Box<str> {
666 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
667 String::from_sqlite_integer(value).map(String::into_boxed_str)
668 }
669
670 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
671 String::from_sqlite_text(value).map(String::into_boxed_str)
672 }
673
674 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
675 String::from_sqlite_real(value).map(String::into_boxed_str)
676 }
677
678 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
679 String::from_sqlite_blob(value).map(String::into_boxed_str)
680 }
681}
682
683impl FromSQLiteValue for Rc<str> {
684 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
685 String::from_sqlite_integer(value).map(Self::from)
686 }
687
688 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
689 String::from_sqlite_text(value).map(Self::from)
690 }
691
692 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
693 String::from_sqlite_real(value).map(Self::from)
694 }
695
696 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
697 String::from_sqlite_blob(value).map(Self::from)
698 }
699}
700
701impl FromSQLiteValue for Arc<str> {
702 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
703 String::from_sqlite_integer(value).map(Self::from)
704 }
705
706 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
707 String::from_sqlite_text(value).map(Self::from)
708 }
709
710 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
711 String::from_sqlite_real(value).map(Self::from)
712 }
713
714 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
715 String::from_sqlite_blob(value).map(Self::from)
716 }
717}
718
719impl FromSQLiteValue for Vec<u8> {
720 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
721 Ok(value.to_le_bytes().to_vec())
722 }
723
724 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
725 Ok(value.as_bytes().to_vec())
726 }
727
728 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
729 Ok(value.to_le_bytes().to_vec())
730 }
731
732 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
733 Ok(value.to_vec())
734 }
735}
736
737#[cfg(feature = "bytes")]
738impl FromSQLiteValue for bytes::Bytes {
739 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
740 Vec::<u8>::from_sqlite_integer(value).map(Self::from)
741 }
742
743 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
744 Vec::<u8>::from_sqlite_text(value).map(Self::from)
745 }
746
747 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
748 Vec::<u8>::from_sqlite_real(value).map(Self::from)
749 }
750
751 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
752 Ok(Self::copy_from_slice(value))
753 }
754}
755
756#[cfg(feature = "bytes")]
757impl FromSQLiteValue for bytes::BytesMut {
758 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
759 Vec::<u8>::from_sqlite_integer(value).map(|v| Self::from(v.as_slice()))
760 }
761
762 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
763 Vec::<u8>::from_sqlite_text(value).map(|v| Self::from(v.as_slice()))
764 }
765
766 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
767 Vec::<u8>::from_sqlite_real(value).map(|v| Self::from(v.as_slice()))
768 }
769
770 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
771 Ok(Self::from(value))
772 }
773}
774
775#[cfg(feature = "smallvec")]
776impl<const N: usize> FromSQLiteValue for smallvec::SmallVec<[u8; N]> {
777 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
778 Err(DrizzleError::ConversionError(
779 "cannot convert INTEGER to SmallVec<u8>, use BLOB".into(),
780 ))
781 }
782
783 fn from_sqlite_text(_value: &str) -> Result<Self, DrizzleError> {
784 Err(DrizzleError::ConversionError(
785 "cannot convert TEXT to SmallVec<u8>, use BLOB".into(),
786 ))
787 }
788
789 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
790 Err(DrizzleError::ConversionError(
791 "cannot convert REAL to SmallVec<u8>, use BLOB".into(),
792 ))
793 }
794
795 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
796 let mut out = Self::new();
797 out.extend_from_slice(value);
798 Ok(out)
799 }
800}
801
802impl FromSQLiteValue for Box<Vec<u8>> {
803 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
804 Vec::<u8>::from_sqlite_integer(value).map(Self::new)
805 }
806
807 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
808 Vec::<u8>::from_sqlite_text(value).map(Self::new)
809 }
810
811 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
812 Vec::<u8>::from_sqlite_real(value).map(Self::new)
813 }
814
815 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
816 Vec::<u8>::from_sqlite_blob(value).map(Self::new)
817 }
818}
819
820impl FromSQLiteValue for Rc<Vec<u8>> {
821 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
822 Vec::<u8>::from_sqlite_integer(value).map(Self::new)
823 }
824
825 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
826 Vec::<u8>::from_sqlite_text(value).map(Self::new)
827 }
828
829 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
830 Vec::<u8>::from_sqlite_real(value).map(Self::new)
831 }
832
833 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
834 Vec::<u8>::from_sqlite_blob(value).map(Self::new)
835 }
836}
837
838impl FromSQLiteValue for Arc<Vec<u8>> {
839 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
840 Vec::<u8>::from_sqlite_integer(value).map(Self::new)
841 }
842
843 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
844 Vec::<u8>::from_sqlite_text(value).map(Self::new)
845 }
846
847 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
848 Vec::<u8>::from_sqlite_real(value).map(Self::new)
849 }
850
851 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
852 Vec::<u8>::from_sqlite_blob(value).map(Self::new)
853 }
854}
855
856impl<T: FromSQLiteValue> FromSQLiteValue for Option<T> {
858 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
859 T::from_sqlite_integer(value).map(Some)
860 }
861
862 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
863 T::from_sqlite_text(value).map(Some)
864 }
865
866 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
867 T::from_sqlite_real(value).map(Some)
868 }
869
870 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
871 T::from_sqlite_blob(value).map(Some)
872 }
873
874 fn from_sqlite_null() -> Result<Self, DrizzleError> {
875 Ok(None)
876 }
877}
878
879#[cfg(feature = "rusqlite")]
884impl DrizzleRowByIndex for rusqlite::Row<'_> {
885 fn get_column<T: FromSQLiteValue>(&self, idx: usize) -> Result<T, DrizzleError> {
886 let value_ref = self.get_ref(idx)?;
887 match value_ref {
888 rusqlite::types::ValueRef::Integer(i) => T::from_sqlite_integer(i),
889 rusqlite::types::ValueRef::Text(s) => {
890 let s = core::str::from_utf8(s).map_err(|e| {
891 DrizzleError::ConversionError(format!("invalid UTF-8: {e}").into())
892 })?;
893 T::from_sqlite_text(s)
894 }
895 rusqlite::types::ValueRef::Real(r) => T::from_sqlite_real(r),
896 rusqlite::types::ValueRef::Blob(b) => T::from_sqlite_blob(b),
897 rusqlite::types::ValueRef::Null => T::from_sqlite_null(),
898 }
899 }
900}
901
902#[cfg(feature = "rusqlite")]
903impl DrizzleRowByName for rusqlite::Row<'_> {
904 fn get_column_by_name<T: FromSQLiteValue>(&self, name: &str) -> Result<T, DrizzleError> {
905 let idx = self.as_ref().column_index(name)?;
906 DrizzleRowByIndex::get_column(self, idx)
907 }
908}
909
910#[cfg(feature = "libsql")]
911impl DrizzleRowByIndex for libsql::Row {
912 fn get_column<T: FromSQLiteValue>(&self, idx: usize) -> Result<T, DrizzleError> {
913 let idx_i32 = i32::try_from(idx).map_err(|e| {
914 DrizzleError::ConversionError(format!("column index {idx} out of range: {e}").into())
915 })?;
916 let value = self.get_value(idx_i32)?;
917 match value {
918 libsql::Value::Integer(i) => T::from_sqlite_integer(i),
919 libsql::Value::Text(ref s) => T::from_sqlite_text(s),
920 libsql::Value::Real(r) => T::from_sqlite_real(r),
921 libsql::Value::Blob(ref b) => T::from_sqlite_blob(b),
922 libsql::Value::Null => T::from_sqlite_null(),
923 }
924 }
925}
926
927#[cfg(feature = "libsql")]
928impl DrizzleRowByName for libsql::Row {
929 fn get_column_by_name<T: FromSQLiteValue>(&self, name: &str) -> Result<T, DrizzleError> {
930 let idx = (0..self.column_count())
931 .find(|&i| self.column_name(i) == Some(name))
932 .ok_or_else(|| {
933 DrizzleError::ConversionError(format!("column '{name}' not found").into())
934 })?;
935
936 let idx_usize = usize::try_from(idx).map_err(|e| {
937 DrizzleError::ConversionError(format!("column index {idx} negative: {e}").into())
938 })?;
939 DrizzleRowByIndex::get_column(self, idx_usize)
940 }
941}
942
943#[cfg(feature = "turso")]
944impl DrizzleRowByIndex for turso::Row {
945 fn get_column<T: FromSQLiteValue>(&self, idx: usize) -> Result<T, DrizzleError> {
946 let value = self.get_value(idx)?;
947 if value.is_null() {
948 T::from_sqlite_null()
949 } else if let Some(&i) = value.as_integer() {
950 T::from_sqlite_integer(i)
951 } else if let Some(s) = value.as_text() {
952 T::from_sqlite_text(s)
953 } else if let Some(&r) = value.as_real() {
954 T::from_sqlite_real(r)
955 } else if let Some(b) = value.as_blob() {
956 T::from_sqlite_blob(b)
957 } else {
958 Err(DrizzleError::ConversionError(
959 "unknown SQLite value type".into(),
960 ))
961 }
962 }
963}
964
965#[cfg(feature = "uuid")]
970impl FromSQLiteValue for uuid::Uuid {
971 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
972 Err(DrizzleError::ConversionError(
973 "cannot convert INTEGER to UUID".into(),
974 ))
975 }
976
977 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
978 Self::parse_str(value).map_err(|e| {
979 DrizzleError::ConversionError(format!("invalid UUID string '{value}': {e}").into())
980 })
981 }
982
983 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
984 Err(DrizzleError::ConversionError(
985 "cannot convert REAL to UUID".into(),
986 ))
987 }
988
989 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
990 Self::from_slice(value)
991 .map_err(|e| DrizzleError::ConversionError(format!("invalid UUID bytes: {e}").into()))
992 }
993}
994
995#[cfg(feature = "chrono")]
1000impl FromSQLiteValue for chrono::NaiveDate {
1001 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1002 Err(DrizzleError::ConversionError(
1003 "cannot convert INTEGER to NaiveDate".into(),
1004 ))
1005 }
1006
1007 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1008 value.parse().map_err(|e| {
1009 DrizzleError::ConversionError(
1010 format!("cannot parse '{value}' as NaiveDate: {e}").into(),
1011 )
1012 })
1013 }
1014
1015 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1016 Err(DrizzleError::ConversionError(
1017 "cannot convert REAL to NaiveDate".into(),
1018 ))
1019 }
1020
1021 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1022 Err(DrizzleError::ConversionError(
1023 "cannot convert BLOB to NaiveDate".into(),
1024 ))
1025 }
1026}
1027
1028#[cfg(feature = "chrono")]
1029impl FromSQLiteValue for chrono::NaiveTime {
1030 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1031 Err(DrizzleError::ConversionError(
1032 "cannot convert INTEGER to NaiveTime".into(),
1033 ))
1034 }
1035
1036 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1037 value.parse().map_err(|e| {
1038 DrizzleError::ConversionError(
1039 format!("cannot parse '{value}' as NaiveTime: {e}").into(),
1040 )
1041 })
1042 }
1043
1044 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1045 Err(DrizzleError::ConversionError(
1046 "cannot convert REAL to NaiveTime".into(),
1047 ))
1048 }
1049
1050 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1051 Err(DrizzleError::ConversionError(
1052 "cannot convert BLOB to NaiveTime".into(),
1053 ))
1054 }
1055}
1056
1057#[cfg(feature = "chrono")]
1058impl FromSQLiteValue for chrono::NaiveDateTime {
1059 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1060 Err(DrizzleError::ConversionError(
1061 "cannot convert INTEGER to NaiveDateTime".into(),
1062 ))
1063 }
1064
1065 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1066 chrono_text::naive(value).map_err(|e| {
1067 DrizzleError::ConversionError(
1068 format!("cannot parse '{value}' as NaiveDateTime: {e}").into(),
1069 )
1070 })
1071 }
1072
1073 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1074 Err(DrizzleError::ConversionError(
1075 "cannot convert REAL to NaiveDateTime".into(),
1076 ))
1077 }
1078
1079 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1080 Err(DrizzleError::ConversionError(
1081 "cannot convert BLOB to NaiveDateTime".into(),
1082 ))
1083 }
1084}
1085
1086#[cfg(feature = "chrono")]
1087impl FromSQLiteValue for chrono::DateTime<chrono::FixedOffset> {
1088 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1089 Err(DrizzleError::ConversionError(
1090 "cannot convert INTEGER to DateTime<FixedOffset>".into(),
1091 ))
1092 }
1093
1094 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1095 chrono_text::fixed(value).map_err(|e| {
1096 DrizzleError::ConversionError(
1097 format!("cannot parse '{value}' as DateTime<FixedOffset>: {e}").into(),
1098 )
1099 })
1100 }
1101
1102 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1103 Err(DrizzleError::ConversionError(
1104 "cannot convert REAL to DateTime<FixedOffset>".into(),
1105 ))
1106 }
1107
1108 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1109 Err(DrizzleError::ConversionError(
1110 "cannot convert BLOB to DateTime<FixedOffset>".into(),
1111 ))
1112 }
1113}
1114
1115#[cfg(feature = "chrono")]
1116impl FromSQLiteValue for chrono::DateTime<chrono::Utc> {
1117 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1118 Err(DrizzleError::ConversionError(
1119 "cannot convert INTEGER to DateTime<Utc>".into(),
1120 ))
1121 }
1122
1123 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1124 chrono_text::utc(value).map_err(|e| {
1125 DrizzleError::ConversionError(
1126 format!("cannot parse '{value}' as DateTime<Utc>: {e}").into(),
1127 )
1128 })
1129 }
1130
1131 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1132 Err(DrizzleError::ConversionError(
1133 "cannot convert REAL to DateTime<Utc>".into(),
1134 ))
1135 }
1136
1137 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1138 Err(DrizzleError::ConversionError(
1139 "cannot convert BLOB to DateTime<Utc>".into(),
1140 ))
1141 }
1142}
1143
1144#[cfg(feature = "chrono")]
1155pub(crate) mod chrono_text {
1156 use chrono::{DateTime, FixedOffset, NaiveDateTime, Offset, ParseResult, Utc};
1157
1158 pub(crate) fn naive(text: &str) -> ParseResult<NaiveDateTime> {
1160 NaiveDateTime::parse_from_str(text, "%Y-%m-%d %H:%M:%S%.f").or_else(|_| text.parse())
1161 }
1162
1163 pub(crate) fn fixed(text: &str) -> ParseResult<DateTime<FixedOffset>> {
1165 DateTime::parse_from_rfc3339(text).or_else(|error| {
1166 naive(text)
1167 .map(|value| DateTime::from_naive_utc_and_offset(value, Utc.fix()))
1168 .map_err(|_| error)
1169 })
1170 }
1171
1172 pub(crate) fn utc(text: &str) -> ParseResult<DateTime<Utc>> {
1174 text.parse().or_else(|error| {
1175 naive(text)
1176 .map(|value| DateTime::from_naive_utc_and_offset(value, Utc))
1177 .map_err(|_| error)
1178 })
1179 }
1180}
1181
1182#[cfg(feature = "time")]
1188pub(crate) mod time_text {
1189 use time::format_description::well_known::{Iso8601, Rfc3339};
1190 use time::macros::format_description;
1191
1192 pub(crate) fn time(text: &str) -> Result<time::Time, time::error::Parse> {
1195 let text = text.strip_prefix('T').unwrap_or(text);
1196 time::Time::parse(
1197 text,
1198 format_description!("[hour]:[minute]:[second].[subsecond]"),
1199 )
1200 .or_else(|_| time::Time::parse(text, format_description!("[hour]:[minute]:[second]")))
1201 }
1202
1203 pub(crate) fn primitive(text: &str) -> Result<time::PrimitiveDateTime, time::error::Parse> {
1205 time::PrimitiveDateTime::parse(text, &Iso8601::DATE_TIME)
1206 .or_else(|_| {
1207 time::PrimitiveDateTime::parse(
1208 text,
1209 format_description!(
1210 "[year]-[month]-[day] [hour]:[minute]:[second].[subsecond]"
1211 ),
1212 )
1213 })
1214 .or_else(|_| {
1215 time::PrimitiveDateTime::parse(
1216 text,
1217 format_description!("[year]-[month]-[day] [hour]:[minute]:[second]"),
1218 )
1219 })
1220 }
1221
1222 pub(crate) fn offset(text: &str) -> Result<time::OffsetDateTime, time::error::Parse> {
1224 time::OffsetDateTime::parse(text, &Rfc3339).or_else(|error| {
1225 primitive(text)
1226 .map(time::PrimitiveDateTime::assume_utc)
1227 .map_err(|_| error)
1228 })
1229 }
1230}
1231
1232#[cfg(feature = "time")]
1233impl FromSQLiteValue for time::Date {
1234 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1235 Err(DrizzleError::ConversionError(
1236 "cannot convert INTEGER to time::Date".into(),
1237 ))
1238 }
1239
1240 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1241 Self::parse(value, &time::format_description::well_known::Iso8601::DATE).map_err(|e| {
1242 DrizzleError::ConversionError(
1243 format!("cannot parse '{value}' as time::Date: {e}").into(),
1244 )
1245 })
1246 }
1247
1248 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1249 Err(DrizzleError::ConversionError(
1250 "cannot convert REAL to time::Date".into(),
1251 ))
1252 }
1253
1254 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1255 Err(DrizzleError::ConversionError(
1256 "cannot convert BLOB to time::Date".into(),
1257 ))
1258 }
1259}
1260
1261#[cfg(feature = "time")]
1262impl FromSQLiteValue for time::Time {
1263 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1264 Err(DrizzleError::ConversionError(
1265 "cannot convert INTEGER to time::Time".into(),
1266 ))
1267 }
1268
1269 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1270 time_text::time(value).map_err(|e| {
1271 DrizzleError::ConversionError(
1272 format!("cannot parse '{value}' as time::Time: {e}").into(),
1273 )
1274 })
1275 }
1276
1277 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1278 Err(DrizzleError::ConversionError(
1279 "cannot convert REAL to time::Time".into(),
1280 ))
1281 }
1282
1283 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1284 Err(DrizzleError::ConversionError(
1285 "cannot convert BLOB to time::Time".into(),
1286 ))
1287 }
1288}
1289
1290#[cfg(feature = "time")]
1291impl FromSQLiteValue for time::PrimitiveDateTime {
1292 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1293 Err(DrizzleError::ConversionError(
1294 "cannot convert INTEGER to time::PrimitiveDateTime".into(),
1295 ))
1296 }
1297
1298 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1299 time_text::primitive(value).map_err(|e| {
1300 DrizzleError::ConversionError(
1301 format!("cannot parse '{value}' as time::PrimitiveDateTime: {e}").into(),
1302 )
1303 })
1304 }
1305
1306 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1307 Err(DrizzleError::ConversionError(
1308 "cannot convert REAL to time::PrimitiveDateTime".into(),
1309 ))
1310 }
1311
1312 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1313 Err(DrizzleError::ConversionError(
1314 "cannot convert BLOB to time::PrimitiveDateTime".into(),
1315 ))
1316 }
1317}
1318
1319#[cfg(feature = "time")]
1320impl FromSQLiteValue for time::OffsetDateTime {
1321 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1322 Err(DrizzleError::ConversionError(
1323 "cannot convert INTEGER to time::OffsetDateTime".into(),
1324 ))
1325 }
1326
1327 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1328 time_text::offset(value).map_err(|e| {
1329 DrizzleError::ConversionError(
1330 format!("cannot parse '{value}' as time::OffsetDateTime: {e}").into(),
1331 )
1332 })
1333 }
1334
1335 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1336 Err(DrizzleError::ConversionError(
1337 "cannot convert REAL to time::OffsetDateTime".into(),
1338 ))
1339 }
1340
1341 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1342 Err(DrizzleError::ConversionError(
1343 "cannot convert BLOB to time::OffsetDateTime".into(),
1344 ))
1345 }
1346}
1347
1348#[cfg(feature = "jiff")]
1354fn parse_jiff<T: core::str::FromStr<Err = jiff::Error>>(
1355 value: &str,
1356 name: &str,
1357) -> Result<T, DrizzleError> {
1358 value.parse().map_err(|e: jiff::Error| {
1359 DrizzleError::ConversionError(format!("cannot parse '{value}' as {name}: {e}").into())
1360 })
1361}
1362
1363#[cfg(feature = "jiff")]
1365macro_rules! impl_from_sqlite_value_jiff {
1366 ($($ty:ty => $name:literal, $parse:expr;)+) => {$(
1367 impl FromSQLiteValue for $ty {
1368 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1369 Err(DrizzleError::ConversionError(
1370 concat!("cannot convert INTEGER to ", $name).into(),
1371 ))
1372 }
1373
1374 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1375 $parse(value)
1376 }
1377
1378 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1379 Err(DrizzleError::ConversionError(
1380 concat!("cannot convert REAL to ", $name).into(),
1381 ))
1382 }
1383
1384 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1385 Err(DrizzleError::ConversionError(
1386 concat!("cannot convert BLOB to ", $name).into(),
1387 ))
1388 }
1389 }
1390 )+};
1391}
1392
1393#[cfg(feature = "jiff")]
1394impl_from_sqlite_value_jiff! {
1395 jiff::civil::Date => "jiff::civil::Date",
1396 |value| parse_jiff(value, "jiff::civil::Date");
1397 jiff::civil::Time => "jiff::civil::Time",
1398 |value| parse_jiff(value, "jiff::civil::Time");
1399 jiff::civil::DateTime => "jiff::civil::DateTime",
1400 |value| parse_jiff(value, "jiff::civil::DateTime");
1401 jiff::Timestamp => "jiff::Timestamp", |value: &str| {
1404 value.parse().or_else(|_| {
1405 let civil: jiff::civil::DateTime = parse_jiff(value, "jiff::Timestamp")?;
1406 jiff::tz::Offset::UTC.to_timestamp(civil).map_err(|e| {
1407 DrizzleError::ConversionError(
1408 format!("cannot convert '{value}' to jiff::Timestamp: {e}").into(),
1409 )
1410 })
1411 })
1412 };
1413}
1414
1415#[cfg(feature = "rust-decimal")]
1420impl FromSQLiteValue for rust_decimal::Decimal {
1421 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
1422 Ok(Self::from(value))
1423 }
1424
1425 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1426 value.parse().map_err(|e| {
1427 DrizzleError::ConversionError(format!("cannot parse '{value}' as Decimal: {e}").into())
1428 })
1429 }
1430
1431 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
1432 Self::try_from(value).map_err(|e| {
1433 DrizzleError::ConversionError(
1434 format!("cannot convert REAL {value} to Decimal: {e}").into(),
1435 )
1436 })
1437 }
1438
1439 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1440 Err(DrizzleError::ConversionError(
1441 "cannot convert BLOB to Decimal".into(),
1442 ))
1443 }
1444}
1445
1446#[cfg(feature = "chrono")]
1451impl FromSQLiteValue for chrono::Duration {
1452 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
1453 Ok(Self::seconds(value))
1454 }
1455
1456 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1457 let error = || {
1458 DrizzleError::ConversionError(
1459 format!("cannot parse '{value}' as chrono::Duration").into(),
1460 )
1461 };
1462 let (negative, secs, nanos) = crate::values::duration::parse(value).ok_or_else(error)?;
1463 let secs = i64::try_from(secs).map_err(|_| error())?;
1464 let duration = Self::new(secs, nanos).ok_or_else(error)?;
1465 Ok(if negative { -duration } else { duration })
1466 }
1467
1468 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
1469 let millis: i64 = format!("{:.0}", value * 1000.0).parse().map_err(|e| {
1470 DrizzleError::ConversionError(
1471 format!("cannot convert REAL {value} to chrono::Duration: {e}").into(),
1472 )
1473 })?;
1474 Ok(Self::milliseconds(millis))
1475 }
1476
1477 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1478 Err(DrizzleError::ConversionError(
1479 "cannot convert BLOB to chrono::Duration".into(),
1480 ))
1481 }
1482}
1483
1484#[cfg(feature = "time")]
1485impl FromSQLiteValue for time::Duration {
1486 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
1487 Ok(Self::seconds(value))
1488 }
1489
1490 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1491 let error = || {
1492 DrizzleError::ConversionError(
1493 format!("cannot parse '{value}' as time::Duration").into(),
1494 )
1495 };
1496 let (negative, secs, nanos) = crate::values::duration::parse(value).ok_or_else(error)?;
1497 let secs = i64::try_from(secs).map_err(|_| error())?;
1498 let duration = Self::new(secs, nanos as i32);
1500 Ok(if negative { -duration } else { duration })
1501 }
1502
1503 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
1504 Ok(Self::seconds_f64(value))
1505 }
1506
1507 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1508 Err(DrizzleError::ConversionError(
1509 "cannot convert BLOB to time::Duration".into(),
1510 ))
1511 }
1512}
1513
1514#[cfg(feature = "serde")]
1519impl FromSQLiteValue for serde_json::Value {
1520 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
1521 Ok(Self::Number(value.into()))
1522 }
1523
1524 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1525 serde_json::from_str(value).map_err(|e| {
1526 DrizzleError::ConversionError(format!("cannot parse '{value}' as JSON: {e}").into())
1527 })
1528 }
1529
1530 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
1531 serde_json::Number::from_f64(value)
1532 .map(serde_json::Value::Number)
1533 .ok_or_else(|| {
1534 DrizzleError::ConversionError(
1535 format!("cannot convert non-finite REAL {value} to JSON").into(),
1536 )
1537 })
1538 }
1539
1540 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
1541 serde_json::from_slice(value).map_err(|e| {
1542 DrizzleError::ConversionError(format!("cannot parse BLOB as JSON: {e}").into())
1543 })
1544 }
1545}
1546
1547#[cfg(feature = "arrayvec")]
1552impl<const N: usize> FromSQLiteValue for arrayvec::ArrayString<N> {
1553 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
1554 let s = value.to_string();
1555 Self::from(&s).map_err(|_| {
1556 DrizzleError::ConversionError(
1557 format!(
1558 "String length {} exceeds ArrayString capacity {}",
1559 s.len(),
1560 N
1561 )
1562 .into(),
1563 )
1564 })
1565 }
1566
1567 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1568 Self::from(value).map_err(|_| {
1569 DrizzleError::ConversionError(
1570 format!(
1571 "Text length {} exceeds ArrayString capacity {}",
1572 value.len(),
1573 N
1574 )
1575 .into(),
1576 )
1577 })
1578 }
1579
1580 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
1581 let s = value.to_string();
1582 Self::from(&s).map_err(|_| {
1583 DrizzleError::ConversionError(
1584 format!(
1585 "String length {} exceeds ArrayString capacity {}",
1586 s.len(),
1587 N
1588 )
1589 .into(),
1590 )
1591 })
1592 }
1593
1594 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
1595 let s = String::from_utf8(value.to_vec())
1596 .map_err(|e| DrizzleError::ConversionError(format!("invalid UTF-8: {e}").into()))?;
1597 Self::from(&s).map_err(|_| {
1598 DrizzleError::ConversionError(
1599 format!(
1600 "String length {} exceeds ArrayString capacity {}",
1601 s.len(),
1602 N
1603 )
1604 .into(),
1605 )
1606 })
1607 }
1608}
1609
1610#[cfg(feature = "arrayvec")]
1611impl<const N: usize> FromSQLiteValue for arrayvec::ArrayVec<u8, N> {
1612 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1613 Err(DrizzleError::ConversionError(
1614 "cannot convert INTEGER to ArrayVec<u8>, use BLOB".into(),
1615 ))
1616 }
1617
1618 fn from_sqlite_text(_value: &str) -> Result<Self, DrizzleError> {
1619 Err(DrizzleError::ConversionError(
1620 "cannot convert TEXT to ArrayVec<u8>, use BLOB".into(),
1621 ))
1622 }
1623
1624 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1625 Err(DrizzleError::ConversionError(
1626 "cannot convert REAL to ArrayVec<u8>, use BLOB".into(),
1627 ))
1628 }
1629
1630 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
1631 Self::try_from(value).map_err(|_| {
1632 DrizzleError::ConversionError(
1633 format!(
1634 "Blob length {} exceeds ArrayVec capacity {}",
1635 value.len(),
1636 N
1637 )
1638 .into(),
1639 )
1640 })
1641 }
1642}