1use crate::prelude::*;
7use crate::values::{OwnedSQLiteValue, SQLiteValue, SQLiteValueRef};
8use drizzle_core::conv::checked_float_to_int;
9use drizzle_core::error::DrizzleError;
10
11pub trait SQLiteAffinity: drizzle_core::types::DataType {
13 const SQL_TYPE: &'static str;
15}
16
17macro_rules! impl_sqlite_affinity {
18 ($($marker:ty => $sql_type:literal),+ $(,)?) => {
19 $(
20 impl SQLiteAffinity for $marker {
21 const SQL_TYPE: &'static str = $sql_type;
22 }
23 )+
24 };
25}
26
27impl_sqlite_affinity! {
28 crate::types::Integer => "INTEGER",
29 crate::types::Text => "TEXT",
30 crate::types::Blob => "BLOB",
31 crate::types::Real => "REAL",
32 crate::types::Numeric => "NUMERIC",
33 crate::types::Any => "ANY",
34}
35
36#[diagnostic::on_unimplemented(
56 message = "`{Self}` cannot be used as a SQLite column type",
57 note = "add #[derive(SQLiteEnum)] for enum types, or use a supported primitive type"
58)]
59pub trait DrizzleSQLiteColumn: Sized {
60 type SQLType: SQLiteAffinity;
65
66 const SQL_TYPE: &'static str = <Self::SQLType as SQLiteAffinity>::SQL_TYPE;
73
74 fn decode(value: SQLiteValueRef<'_>) -> Result<Self, DrizzleError>;
84
85 fn encode(&self) -> SQLiteValue<'_>;
87
88 fn encode_owned(self) -> OwnedSQLiteValue {
94 self.encode().into_owned()
95 }
96
97 #[cfg(feature = "query")]
105 fn decode_json(value: &serde_json::Value) -> Result<Self, DrizzleError> {
106 let value = decode_projected_sqlite_value(value)?;
107 let value = value.as_value();
108 Self::decode(value.as_ref())
109 }
110}
111
112#[cfg(feature = "query")]
124pub fn decode_projected_sqlite_value(
125 value: &serde_json::Value,
126) -> Result<OwnedSQLiteValue, DrizzleError> {
127 if value.is_null() {
128 return Ok(OwnedSQLiteValue::Null);
129 }
130
131 let object = value.as_object().ok_or_else(|| {
132 DrizzleError::ConversionError("SQLite query value is missing its storage tag".into())
133 })?;
134 let storage = object
135 .get("$drizzle_storage")
136 .and_then(serde_json::Value::as_str)
137 .ok_or_else(|| {
138 DrizzleError::ConversionError("SQLite query value has no valid $drizzle_storage".into())
139 })?;
140 let value = object.get("$drizzle_value").ok_or_else(|| {
141 DrizzleError::ConversionError("SQLite query value has no $drizzle_value".into())
142 })?;
143
144 match storage {
145 "integer" => value
146 .as_i64()
147 .map(OwnedSQLiteValue::Integer)
148 .ok_or_else(|| {
149 DrizzleError::ConversionError(
150 "SQLite INTEGER query value is not a JSON integer".into(),
151 )
152 }),
153 "real" => value.as_f64().map(OwnedSQLiteValue::Real).ok_or_else(|| {
154 DrizzleError::ConversionError("SQLite REAL query value is not a JSON number".into())
155 }),
156 "text" => value
157 .as_str()
158 .map(|value| OwnedSQLiteValue::Text(value.to_owned()))
159 .ok_or_else(|| {
160 DrizzleError::ConversionError("SQLite TEXT query value is not a JSON string".into())
161 }),
162 "blob" => value
163 .as_str()
164 .ok_or_else(|| {
165 DrizzleError::ConversionError("SQLite BLOB query value is not a hex string".into())
166 })
167 .and_then(decode_projected_blob)
168 .map(|value| OwnedSQLiteValue::Blob(value.into_boxed_slice())),
169 other => Err(DrizzleError::ConversionError(
170 format!("unknown SQLite query storage class `{other}`").into(),
171 )),
172 }
173}
174
175#[cfg(feature = "query")]
176fn decode_projected_blob(value: &str) -> Result<Vec<u8>, DrizzleError> {
177 let (chunks, remainder) = value.as_bytes().as_chunks::<2>();
178 let mut bytes = Vec::with_capacity(value.len() / 2);
179 for chunk in chunks {
180 let high = decode_hex_nibble(chunk[0])?;
181 let low = decode_hex_nibble(chunk[1])?;
182 bytes.push((high << 4) | low);
183 }
184 if !remainder.is_empty() {
185 return Err(DrizzleError::ConversionError(
186 "hex-encoded SQLite BLOB has odd length".into(),
187 ));
188 }
189 Ok(bytes)
190}
191
192#[cfg(feature = "query")]
193fn decode_hex_nibble(value: u8) -> Result<u8, DrizzleError> {
194 match value {
195 b'0'..=b'9' => Ok(value - b'0'),
196 b'a'..=b'f' => Ok(value - b'a' + 10),
197 b'A'..=b'F' => Ok(value - b'A' + 10),
198 _ => Err(DrizzleError::ConversionError(
199 "SQLite BLOB query value contains a non-hex byte".into(),
200 )),
201 }
202}
203
204impl<'a, T> From<T> for SQLiteValue<'a>
205where
206 T: DrizzleSQLiteColumn,
207{
208 fn from(value: T) -> Self {
209 value.encode_owned().into()
210 }
211}
212
213pub trait FromSQLiteValue: Sized {
224 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError>;
230
231 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError>;
237
238 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError>;
244
245 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError>;
251
252 fn from_sqlite_ref(value: SQLiteValueRef<'_>) -> Result<Self, DrizzleError> {
259 match value {
260 SQLiteValueRef::Integer(value) => Self::from_sqlite_integer(value),
261 SQLiteValueRef::Text(value) => Self::from_sqlite_text(value),
262 SQLiteValueRef::Real(value) => Self::from_sqlite_real(value),
263 SQLiteValueRef::Blob(value) => Self::from_sqlite_blob(value),
264 SQLiteValueRef::Null => Self::from_sqlite_null(),
265 }
266 }
267
268 fn from_sqlite_null() -> Result<Self, DrizzleError> {
275 Err(DrizzleError::ConversionError(
276 "unexpected NULL value".into(),
277 ))
278 }
279
280 #[cfg(feature = "rusqlite")]
287 fn from_value_ref(value: ::rusqlite::types::ValueRef<'_>) -> Result<Self, DrizzleError> {
288 let value = SQLiteValueRef::try_from_rusqlite_value_ref(value)?;
289 Self::from_sqlite_ref(value)
290 }
291}
292
293impl<T> FromSQLiteValue for T
294where
295 T: DrizzleSQLiteColumn,
296{
297 fn from_sqlite_ref(value: SQLiteValueRef<'_>) -> Result<Self, DrizzleError> {
298 T::decode(value)
299 }
300
301 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
302 T::decode(SQLiteValueRef::Integer(value))
303 }
304
305 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
306 T::decode(SQLiteValueRef::Text(value))
307 }
308
309 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
310 T::decode(SQLiteValueRef::Real(value))
311 }
312
313 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
314 T::decode(SQLiteValueRef::Blob(value))
315 }
316
317 fn from_sqlite_null() -> Result<Self, DrizzleError> {
318 T::decode(SQLiteValueRef::Null)
319 }
320}
321
322pub trait DrizzleRowByIndex {
324 fn get_column<T: FromSQLiteValue>(&self, idx: usize) -> Result<T, DrizzleError>;
331}
332
333pub trait DrizzleRowByName: DrizzleRowByIndex {
335 fn get_column_by_name<T: FromSQLiteValue>(&self, name: &str) -> Result<T, DrizzleError>;
342}
343
344macro_rules! impl_from_sqlite_value_int {
350 (i64) => {
352 impl FromSQLiteValue for i64 {
353 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
354 Ok(value)
355 }
356
357 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
358 value.parse().map_err(|e| {
359 DrizzleError::ConversionError(format!("cannot parse '{}' as i64: {}", value, e).into())
360 })
361 }
362
363 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
364 checked_float_to_int(value, "i64")
365 }
366
367 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
368 Err(DrizzleError::ConversionError("cannot convert BLOB to i64".into()))
369 }
370 }
371 };
372 ($($ty:ty),+ $(,)?) => {
374 $(
375 impl FromSQLiteValue for $ty {
376 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
377 value.try_into().map_err(|e| {
378 DrizzleError::ConversionError(
379 format!("i64 {} out of range for {}: {}", value, stringify!($ty), e).into(),
380 )
381 })
382 }
383
384 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
385 value.parse().map_err(|e| {
386 DrizzleError::ConversionError(
387 format!("cannot parse '{}' as {}: {}", value, stringify!($ty), e).into()
388 )
389 })
390 }
391
392 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
393 checked_float_to_int(value, stringify!($ty))
394 }
395
396 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
397 Err(DrizzleError::ConversionError(
398 concat!("cannot convert BLOB to ", stringify!($ty)).into()
399 ))
400 }
401 }
402 )+
403 };
404}
405
406#[inline]
409fn i64_to_f64(i: i64) -> f64 {
410 let high = i32::try_from(i >> 32).expect("sign-extended high word fits in i32");
411 let low = u32::try_from(i & 0xFFFF_FFFF).expect("masked low word fits in u32");
412 f64::from(high) * 4_294_967_296.0_f64 + f64::from(low)
413}
414
415impl_from_sqlite_value_int!(i64);
417impl_from_sqlite_value_int!(i8, i16, i32, isize, u8, u16, u32, u64, usize);
418
419impl FromSQLiteValue for f64 {
422 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
423 Ok(i64_to_f64(value))
424 }
425
426 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
427 value.parse().map_err(|e| {
428 DrizzleError::ConversionError(format!("cannot parse '{value}' as f64: {e}").into())
429 })
430 }
431
432 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
433 Ok(value)
434 }
435
436 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
437 Err(DrizzleError::ConversionError(
438 "cannot convert BLOB to f64".into(),
439 ))
440 }
441}
442
443fn narrow_to_f32(value: f64) -> Result<f32, DrizzleError> {
444 format!("{value}").parse::<f32>().map_err(|e| {
448 DrizzleError::ConversionError(format!("cannot convert REAL {value} to f32: {e}").into())
449 })
450}
451
452impl FromSQLiteValue for f32 {
456 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
457 narrow_to_f32(i64_to_f64(value))
459 }
460
461 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
462 value.parse().map_err(|e| {
463 DrizzleError::ConversionError(format!("cannot parse '{value}' as f32: {e}").into())
464 })
465 }
466
467 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
468 narrow_to_f32(value)
469 }
470
471 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
472 Err(DrizzleError::ConversionError(
473 "cannot convert BLOB to f32".into(),
474 ))
475 }
476}
477
478impl FromSQLiteValue for bool {
479 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
480 Ok(value != 0)
481 }
482
483 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
484 match value.to_lowercase().as_str() {
485 "true" | "1" | "yes" | "on" => Ok(true),
486 "false" | "0" | "no" | "off" => Ok(false),
487 _ => Err(DrizzleError::ConversionError(
488 format!("cannot parse '{value}' as bool").into(),
489 )),
490 }
491 }
492
493 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
494 Ok(value != 0.0)
495 }
496
497 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
498 Err(DrizzleError::ConversionError(
499 "cannot convert BLOB to bool".into(),
500 ))
501 }
502}
503
504impl FromSQLiteValue for String {
505 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
506 Ok(value.to_string())
507 }
508
509 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
510 Ok(value.to_string())
511 }
512
513 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
514 Ok(value.to_string())
515 }
516
517 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
518 Self::from_utf8(value.to_vec()).map_err(|e| {
519 DrizzleError::ConversionError(format!("invalid UTF-8 in BLOB: {e}").into())
520 })
521 }
522}
523
524impl FromSQLiteValue for compact_str::CompactString {
525 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
526 Ok(Self::new(value.to_string()))
527 }
528
529 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
530 Ok(Self::new(value))
531 }
532
533 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
534 Ok(Self::new(value.to_string()))
535 }
536
537 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
538 let s = String::from_utf8(value.to_vec()).map_err(|e| {
539 DrizzleError::ConversionError(format!("invalid UTF-8 in BLOB: {e}").into())
540 })?;
541 Ok(Self::new(s))
542 }
543}
544
545impl FromSQLiteValue for Box<String> {
546 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
547 String::from_sqlite_integer(value).map(Self::new)
548 }
549
550 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
551 String::from_sqlite_text(value).map(Self::new)
552 }
553
554 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
555 String::from_sqlite_real(value).map(Self::new)
556 }
557
558 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
559 String::from_sqlite_blob(value).map(Self::new)
560 }
561}
562
563impl FromSQLiteValue for Rc<String> {
564 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
565 String::from_sqlite_integer(value).map(Self::new)
566 }
567
568 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
569 String::from_sqlite_text(value).map(Self::new)
570 }
571
572 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
573 String::from_sqlite_real(value).map(Self::new)
574 }
575
576 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
577 String::from_sqlite_blob(value).map(Self::new)
578 }
579}
580
581impl FromSQLiteValue for Arc<String> {
582 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
583 String::from_sqlite_integer(value).map(Self::new)
584 }
585
586 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
587 String::from_sqlite_text(value).map(Self::new)
588 }
589
590 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
591 String::from_sqlite_real(value).map(Self::new)
592 }
593
594 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
595 String::from_sqlite_blob(value).map(Self::new)
596 }
597}
598
599impl FromSQLiteValue for Box<str> {
600 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
601 String::from_sqlite_integer(value).map(String::into_boxed_str)
602 }
603
604 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
605 String::from_sqlite_text(value).map(String::into_boxed_str)
606 }
607
608 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
609 String::from_sqlite_real(value).map(String::into_boxed_str)
610 }
611
612 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
613 String::from_sqlite_blob(value).map(String::into_boxed_str)
614 }
615}
616
617impl FromSQLiteValue for Rc<str> {
618 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
619 String::from_sqlite_integer(value).map(Self::from)
620 }
621
622 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
623 String::from_sqlite_text(value).map(Self::from)
624 }
625
626 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
627 String::from_sqlite_real(value).map(Self::from)
628 }
629
630 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
631 String::from_sqlite_blob(value).map(Self::from)
632 }
633}
634
635impl FromSQLiteValue for Arc<str> {
636 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
637 String::from_sqlite_integer(value).map(Self::from)
638 }
639
640 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
641 String::from_sqlite_text(value).map(Self::from)
642 }
643
644 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
645 String::from_sqlite_real(value).map(Self::from)
646 }
647
648 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
649 String::from_sqlite_blob(value).map(Self::from)
650 }
651}
652
653impl FromSQLiteValue for Vec<u8> {
654 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
655 Ok(value.to_le_bytes().to_vec())
656 }
657
658 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
659 Ok(value.as_bytes().to_vec())
660 }
661
662 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
663 Ok(value.to_le_bytes().to_vec())
664 }
665
666 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
667 Ok(value.to_vec())
668 }
669}
670
671#[cfg(feature = "bytes")]
672impl FromSQLiteValue for bytes::Bytes {
673 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
674 Vec::<u8>::from_sqlite_integer(value).map(Self::from)
675 }
676
677 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
678 Vec::<u8>::from_sqlite_text(value).map(Self::from)
679 }
680
681 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
682 Vec::<u8>::from_sqlite_real(value).map(Self::from)
683 }
684
685 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
686 Ok(Self::copy_from_slice(value))
687 }
688}
689
690#[cfg(feature = "bytes")]
691impl FromSQLiteValue for bytes::BytesMut {
692 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
693 Vec::<u8>::from_sqlite_integer(value).map(|v| Self::from(v.as_slice()))
694 }
695
696 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
697 Vec::<u8>::from_sqlite_text(value).map(|v| Self::from(v.as_slice()))
698 }
699
700 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
701 Vec::<u8>::from_sqlite_real(value).map(|v| Self::from(v.as_slice()))
702 }
703
704 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
705 Ok(Self::from(value))
706 }
707}
708
709#[cfg(feature = "smallvec")]
710impl<const N: usize> FromSQLiteValue for smallvec::SmallVec<[u8; N]> {
711 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
712 Err(DrizzleError::ConversionError(
713 "cannot convert INTEGER to SmallVec<u8>, use BLOB".into(),
714 ))
715 }
716
717 fn from_sqlite_text(_value: &str) -> Result<Self, DrizzleError> {
718 Err(DrizzleError::ConversionError(
719 "cannot convert TEXT to SmallVec<u8>, use BLOB".into(),
720 ))
721 }
722
723 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
724 Err(DrizzleError::ConversionError(
725 "cannot convert REAL to SmallVec<u8>, use BLOB".into(),
726 ))
727 }
728
729 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
730 let mut out = Self::new();
731 out.extend_from_slice(value);
732 Ok(out)
733 }
734}
735
736impl FromSQLiteValue for Box<Vec<u8>> {
737 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
738 Vec::<u8>::from_sqlite_integer(value).map(Self::new)
739 }
740
741 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
742 Vec::<u8>::from_sqlite_text(value).map(Self::new)
743 }
744
745 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
746 Vec::<u8>::from_sqlite_real(value).map(Self::new)
747 }
748
749 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
750 Vec::<u8>::from_sqlite_blob(value).map(Self::new)
751 }
752}
753
754impl FromSQLiteValue for Rc<Vec<u8>> {
755 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
756 Vec::<u8>::from_sqlite_integer(value).map(Self::new)
757 }
758
759 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
760 Vec::<u8>::from_sqlite_text(value).map(Self::new)
761 }
762
763 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
764 Vec::<u8>::from_sqlite_real(value).map(Self::new)
765 }
766
767 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
768 Vec::<u8>::from_sqlite_blob(value).map(Self::new)
769 }
770}
771
772impl FromSQLiteValue for Arc<Vec<u8>> {
773 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
774 Vec::<u8>::from_sqlite_integer(value).map(Self::new)
775 }
776
777 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
778 Vec::<u8>::from_sqlite_text(value).map(Self::new)
779 }
780
781 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
782 Vec::<u8>::from_sqlite_real(value).map(Self::new)
783 }
784
785 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
786 Vec::<u8>::from_sqlite_blob(value).map(Self::new)
787 }
788}
789
790impl<T: FromSQLiteValue> FromSQLiteValue for Option<T> {
792 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
793 T::from_sqlite_integer(value).map(Some)
794 }
795
796 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
797 T::from_sqlite_text(value).map(Some)
798 }
799
800 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
801 T::from_sqlite_real(value).map(Some)
802 }
803
804 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
805 T::from_sqlite_blob(value).map(Some)
806 }
807
808 fn from_sqlite_null() -> Result<Self, DrizzleError> {
809 Ok(None)
810 }
811}
812
813#[cfg(feature = "rusqlite")]
818impl DrizzleRowByIndex for rusqlite::Row<'_> {
819 fn get_column<T: FromSQLiteValue>(&self, idx: usize) -> Result<T, DrizzleError> {
820 let value_ref = self.get_ref(idx)?;
821 match value_ref {
822 rusqlite::types::ValueRef::Integer(i) => T::from_sqlite_integer(i),
823 rusqlite::types::ValueRef::Text(s) => {
824 let s = core::str::from_utf8(s).map_err(|e| {
825 DrizzleError::ConversionError(format!("invalid UTF-8: {e}").into())
826 })?;
827 T::from_sqlite_text(s)
828 }
829 rusqlite::types::ValueRef::Real(r) => T::from_sqlite_real(r),
830 rusqlite::types::ValueRef::Blob(b) => T::from_sqlite_blob(b),
831 rusqlite::types::ValueRef::Null => T::from_sqlite_null(),
832 }
833 }
834}
835
836#[cfg(feature = "rusqlite")]
837impl DrizzleRowByName for rusqlite::Row<'_> {
838 fn get_column_by_name<T: FromSQLiteValue>(&self, name: &str) -> Result<T, DrizzleError> {
839 let idx = self.as_ref().column_index(name)?;
840 DrizzleRowByIndex::get_column(self, idx)
841 }
842}
843
844#[cfg(feature = "libsql")]
845impl DrizzleRowByIndex for libsql::Row {
846 fn get_column<T: FromSQLiteValue>(&self, idx: usize) -> Result<T, DrizzleError> {
847 let idx_i32 = i32::try_from(idx).map_err(|e| {
848 DrizzleError::ConversionError(format!("column index {idx} out of range: {e}").into())
849 })?;
850 let value = self.get_value(idx_i32)?;
851 match value {
852 libsql::Value::Integer(i) => T::from_sqlite_integer(i),
853 libsql::Value::Text(ref s) => T::from_sqlite_text(s),
854 libsql::Value::Real(r) => T::from_sqlite_real(r),
855 libsql::Value::Blob(ref b) => T::from_sqlite_blob(b),
856 libsql::Value::Null => T::from_sqlite_null(),
857 }
858 }
859}
860
861#[cfg(feature = "libsql")]
862impl DrizzleRowByName for libsql::Row {
863 fn get_column_by_name<T: FromSQLiteValue>(&self, name: &str) -> Result<T, DrizzleError> {
864 let idx = (0..self.column_count())
865 .find(|&i| self.column_name(i) == Some(name))
866 .ok_or_else(|| {
867 DrizzleError::ConversionError(format!("column '{name}' not found").into())
868 })?;
869
870 let idx_usize = usize::try_from(idx).map_err(|e| {
871 DrizzleError::ConversionError(format!("column index {idx} negative: {e}").into())
872 })?;
873 DrizzleRowByIndex::get_column(self, idx_usize)
874 }
875}
876
877#[cfg(feature = "turso")]
878impl DrizzleRowByIndex for turso::Row {
879 fn get_column<T: FromSQLiteValue>(&self, idx: usize) -> Result<T, DrizzleError> {
880 let value = self.get_value(idx)?;
881 if value.is_null() {
882 T::from_sqlite_null()
883 } else if let Some(&i) = value.as_integer() {
884 T::from_sqlite_integer(i)
885 } else if let Some(s) = value.as_text() {
886 T::from_sqlite_text(s)
887 } else if let Some(&r) = value.as_real() {
888 T::from_sqlite_real(r)
889 } else if let Some(b) = value.as_blob() {
890 T::from_sqlite_blob(b)
891 } else {
892 Err(DrizzleError::ConversionError(
893 "unknown SQLite value type".into(),
894 ))
895 }
896 }
897}
898
899#[cfg(feature = "uuid")]
904impl FromSQLiteValue for uuid::Uuid {
905 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
906 Err(DrizzleError::ConversionError(
907 "cannot convert INTEGER to UUID".into(),
908 ))
909 }
910
911 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
912 Self::parse_str(value).map_err(|e| {
913 DrizzleError::ConversionError(format!("invalid UUID string '{value}': {e}").into())
914 })
915 }
916
917 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
918 Err(DrizzleError::ConversionError(
919 "cannot convert REAL to UUID".into(),
920 ))
921 }
922
923 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
924 Self::from_slice(value)
925 .map_err(|e| DrizzleError::ConversionError(format!("invalid UUID bytes: {e}").into()))
926 }
927}
928
929#[cfg(feature = "chrono")]
934impl FromSQLiteValue for chrono::NaiveDate {
935 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
936 Err(DrizzleError::ConversionError(
937 "cannot convert INTEGER to NaiveDate".into(),
938 ))
939 }
940
941 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
942 value.parse().map_err(|e| {
943 DrizzleError::ConversionError(
944 format!("cannot parse '{value}' as NaiveDate: {e}").into(),
945 )
946 })
947 }
948
949 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
950 Err(DrizzleError::ConversionError(
951 "cannot convert REAL to NaiveDate".into(),
952 ))
953 }
954
955 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
956 Err(DrizzleError::ConversionError(
957 "cannot convert BLOB to NaiveDate".into(),
958 ))
959 }
960}
961
962#[cfg(feature = "chrono")]
963impl FromSQLiteValue for chrono::NaiveTime {
964 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
965 Err(DrizzleError::ConversionError(
966 "cannot convert INTEGER to NaiveTime".into(),
967 ))
968 }
969
970 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
971 value.parse().map_err(|e| {
972 DrizzleError::ConversionError(
973 format!("cannot parse '{value}' as NaiveTime: {e}").into(),
974 )
975 })
976 }
977
978 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
979 Err(DrizzleError::ConversionError(
980 "cannot convert REAL to NaiveTime".into(),
981 ))
982 }
983
984 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
985 Err(DrizzleError::ConversionError(
986 "cannot convert BLOB to NaiveTime".into(),
987 ))
988 }
989}
990
991#[cfg(feature = "chrono")]
992impl FromSQLiteValue for chrono::NaiveDateTime {
993 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
994 Err(DrizzleError::ConversionError(
995 "cannot convert INTEGER to NaiveDateTime".into(),
996 ))
997 }
998
999 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1000 chrono_text::naive(value).map_err(|e| {
1001 DrizzleError::ConversionError(
1002 format!("cannot parse '{value}' as NaiveDateTime: {e}").into(),
1003 )
1004 })
1005 }
1006
1007 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1008 Err(DrizzleError::ConversionError(
1009 "cannot convert REAL to NaiveDateTime".into(),
1010 ))
1011 }
1012
1013 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1014 Err(DrizzleError::ConversionError(
1015 "cannot convert BLOB to NaiveDateTime".into(),
1016 ))
1017 }
1018}
1019
1020#[cfg(feature = "chrono")]
1021impl FromSQLiteValue for chrono::DateTime<chrono::FixedOffset> {
1022 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1023 Err(DrizzleError::ConversionError(
1024 "cannot convert INTEGER to DateTime<FixedOffset>".into(),
1025 ))
1026 }
1027
1028 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1029 chrono_text::fixed(value).map_err(|e| {
1030 DrizzleError::ConversionError(
1031 format!("cannot parse '{value}' as DateTime<FixedOffset>: {e}").into(),
1032 )
1033 })
1034 }
1035
1036 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1037 Err(DrizzleError::ConversionError(
1038 "cannot convert REAL to DateTime<FixedOffset>".into(),
1039 ))
1040 }
1041
1042 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1043 Err(DrizzleError::ConversionError(
1044 "cannot convert BLOB to DateTime<FixedOffset>".into(),
1045 ))
1046 }
1047}
1048
1049#[cfg(feature = "chrono")]
1050impl FromSQLiteValue for chrono::DateTime<chrono::Utc> {
1051 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1052 Err(DrizzleError::ConversionError(
1053 "cannot convert INTEGER to DateTime<Utc>".into(),
1054 ))
1055 }
1056
1057 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1058 chrono_text::utc(value).map_err(|e| {
1059 DrizzleError::ConversionError(
1060 format!("cannot parse '{value}' as DateTime<Utc>: {e}").into(),
1061 )
1062 })
1063 }
1064
1065 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1066 Err(DrizzleError::ConversionError(
1067 "cannot convert REAL to DateTime<Utc>".into(),
1068 ))
1069 }
1070
1071 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1072 Err(DrizzleError::ConversionError(
1073 "cannot convert BLOB to DateTime<Utc>".into(),
1074 ))
1075 }
1076}
1077
1078#[cfg(feature = "chrono")]
1089pub(crate) mod chrono_text {
1090 use chrono::{DateTime, FixedOffset, NaiveDateTime, Offset, ParseResult, Utc};
1091
1092 pub(crate) fn naive(text: &str) -> ParseResult<NaiveDateTime> {
1094 NaiveDateTime::parse_from_str(text, "%Y-%m-%d %H:%M:%S%.f").or_else(|_| text.parse())
1095 }
1096
1097 pub(crate) fn fixed(text: &str) -> ParseResult<DateTime<FixedOffset>> {
1099 DateTime::parse_from_rfc3339(text).or_else(|error| {
1100 naive(text)
1101 .map(|value| DateTime::from_naive_utc_and_offset(value, Utc.fix()))
1102 .map_err(|_| error)
1103 })
1104 }
1105
1106 pub(crate) fn utc(text: &str) -> ParseResult<DateTime<Utc>> {
1108 text.parse().or_else(|error| {
1109 naive(text)
1110 .map(|value| DateTime::from_naive_utc_and_offset(value, Utc))
1111 .map_err(|_| error)
1112 })
1113 }
1114}
1115
1116#[cfg(feature = "time")]
1122pub(crate) mod time_text {
1123 use time::format_description::well_known::{Iso8601, Rfc3339};
1124 use time::macros::format_description;
1125
1126 pub(crate) fn time(text: &str) -> Result<time::Time, time::error::Parse> {
1129 let text = text.strip_prefix('T').unwrap_or(text);
1130 time::Time::parse(
1131 text,
1132 format_description!("[hour]:[minute]:[second].[subsecond]"),
1133 )
1134 .or_else(|_| time::Time::parse(text, format_description!("[hour]:[minute]:[second]")))
1135 }
1136
1137 pub(crate) fn primitive(text: &str) -> Result<time::PrimitiveDateTime, time::error::Parse> {
1139 time::PrimitiveDateTime::parse(text, &Iso8601::DATE_TIME)
1140 .or_else(|_| {
1141 time::PrimitiveDateTime::parse(
1142 text,
1143 format_description!(
1144 "[year]-[month]-[day] [hour]:[minute]:[second].[subsecond]"
1145 ),
1146 )
1147 })
1148 .or_else(|_| {
1149 time::PrimitiveDateTime::parse(
1150 text,
1151 format_description!("[year]-[month]-[day] [hour]:[minute]:[second]"),
1152 )
1153 })
1154 }
1155
1156 pub(crate) fn offset(text: &str) -> Result<time::OffsetDateTime, time::error::Parse> {
1158 time::OffsetDateTime::parse(text, &Rfc3339).or_else(|error| {
1159 primitive(text)
1160 .map(time::PrimitiveDateTime::assume_utc)
1161 .map_err(|_| error)
1162 })
1163 }
1164}
1165
1166#[cfg(feature = "time")]
1167impl FromSQLiteValue for time::Date {
1168 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1169 Err(DrizzleError::ConversionError(
1170 "cannot convert INTEGER to time::Date".into(),
1171 ))
1172 }
1173
1174 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1175 Self::parse(value, &time::format_description::well_known::Iso8601::DATE).map_err(|e| {
1176 DrizzleError::ConversionError(
1177 format!("cannot parse '{value}' as time::Date: {e}").into(),
1178 )
1179 })
1180 }
1181
1182 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1183 Err(DrizzleError::ConversionError(
1184 "cannot convert REAL to time::Date".into(),
1185 ))
1186 }
1187
1188 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1189 Err(DrizzleError::ConversionError(
1190 "cannot convert BLOB to time::Date".into(),
1191 ))
1192 }
1193}
1194
1195#[cfg(feature = "time")]
1196impl FromSQLiteValue for time::Time {
1197 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1198 Err(DrizzleError::ConversionError(
1199 "cannot convert INTEGER to time::Time".into(),
1200 ))
1201 }
1202
1203 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1204 time_text::time(value).map_err(|e| {
1205 DrizzleError::ConversionError(
1206 format!("cannot parse '{value}' as time::Time: {e}").into(),
1207 )
1208 })
1209 }
1210
1211 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1212 Err(DrizzleError::ConversionError(
1213 "cannot convert REAL to time::Time".into(),
1214 ))
1215 }
1216
1217 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1218 Err(DrizzleError::ConversionError(
1219 "cannot convert BLOB to time::Time".into(),
1220 ))
1221 }
1222}
1223
1224#[cfg(feature = "time")]
1225impl FromSQLiteValue for time::PrimitiveDateTime {
1226 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1227 Err(DrizzleError::ConversionError(
1228 "cannot convert INTEGER to time::PrimitiveDateTime".into(),
1229 ))
1230 }
1231
1232 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1233 time_text::primitive(value).map_err(|e| {
1234 DrizzleError::ConversionError(
1235 format!("cannot parse '{value}' as time::PrimitiveDateTime: {e}").into(),
1236 )
1237 })
1238 }
1239
1240 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1241 Err(DrizzleError::ConversionError(
1242 "cannot convert REAL to time::PrimitiveDateTime".into(),
1243 ))
1244 }
1245
1246 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1247 Err(DrizzleError::ConversionError(
1248 "cannot convert BLOB to time::PrimitiveDateTime".into(),
1249 ))
1250 }
1251}
1252
1253#[cfg(feature = "time")]
1254impl FromSQLiteValue for time::OffsetDateTime {
1255 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1256 Err(DrizzleError::ConversionError(
1257 "cannot convert INTEGER to time::OffsetDateTime".into(),
1258 ))
1259 }
1260
1261 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1262 time_text::offset(value).map_err(|e| {
1263 DrizzleError::ConversionError(
1264 format!("cannot parse '{value}' as time::OffsetDateTime: {e}").into(),
1265 )
1266 })
1267 }
1268
1269 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1270 Err(DrizzleError::ConversionError(
1271 "cannot convert REAL to time::OffsetDateTime".into(),
1272 ))
1273 }
1274
1275 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1276 Err(DrizzleError::ConversionError(
1277 "cannot convert BLOB to time::OffsetDateTime".into(),
1278 ))
1279 }
1280}
1281
1282#[cfg(feature = "jiff")]
1288fn parse_jiff<T: core::str::FromStr<Err = jiff::Error>>(
1289 value: &str,
1290 name: &str,
1291) -> Result<T, DrizzleError> {
1292 value.parse().map_err(|e: jiff::Error| {
1293 DrizzleError::ConversionError(format!("cannot parse '{value}' as {name}: {e}").into())
1294 })
1295}
1296
1297#[cfg(feature = "jiff")]
1299macro_rules! impl_from_sqlite_value_jiff {
1300 ($($ty:ty => $name:literal, $parse:expr;)+) => {$(
1301 impl FromSQLiteValue for $ty {
1302 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1303 Err(DrizzleError::ConversionError(
1304 concat!("cannot convert INTEGER to ", $name).into(),
1305 ))
1306 }
1307
1308 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1309 $parse(value)
1310 }
1311
1312 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1313 Err(DrizzleError::ConversionError(
1314 concat!("cannot convert REAL to ", $name).into(),
1315 ))
1316 }
1317
1318 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1319 Err(DrizzleError::ConversionError(
1320 concat!("cannot convert BLOB to ", $name).into(),
1321 ))
1322 }
1323 }
1324 )+};
1325}
1326
1327#[cfg(feature = "jiff")]
1328impl_from_sqlite_value_jiff! {
1329 jiff::civil::Date => "jiff::civil::Date",
1330 |value| parse_jiff(value, "jiff::civil::Date");
1331 jiff::civil::Time => "jiff::civil::Time",
1332 |value| parse_jiff(value, "jiff::civil::Time");
1333 jiff::civil::DateTime => "jiff::civil::DateTime",
1334 |value| parse_jiff(value, "jiff::civil::DateTime");
1335 jiff::Timestamp => "jiff::Timestamp", |value: &str| {
1338 value.parse().or_else(|_| {
1339 let civil: jiff::civil::DateTime = parse_jiff(value, "jiff::Timestamp")?;
1340 jiff::tz::Offset::UTC.to_timestamp(civil).map_err(|e| {
1341 DrizzleError::ConversionError(
1342 format!("cannot convert '{value}' to jiff::Timestamp: {e}").into(),
1343 )
1344 })
1345 })
1346 };
1347}
1348
1349#[cfg(feature = "rust-decimal")]
1354impl FromSQLiteValue for rust_decimal::Decimal {
1355 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
1356 Ok(Self::from(value))
1357 }
1358
1359 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1360 value.parse().map_err(|e| {
1361 DrizzleError::ConversionError(format!("cannot parse '{value}' as Decimal: {e}").into())
1362 })
1363 }
1364
1365 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
1366 Self::try_from(value).map_err(|e| {
1367 DrizzleError::ConversionError(
1368 format!("cannot convert REAL {value} to Decimal: {e}").into(),
1369 )
1370 })
1371 }
1372
1373 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1374 Err(DrizzleError::ConversionError(
1375 "cannot convert BLOB to Decimal".into(),
1376 ))
1377 }
1378}
1379
1380#[cfg(feature = "chrono")]
1385impl FromSQLiteValue for chrono::Duration {
1386 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
1387 Ok(Self::seconds(value))
1388 }
1389
1390 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1391 let secs: i64 = value.trim_end_matches('s').parse().map_err(|e| {
1393 DrizzleError::ConversionError(
1394 format!("cannot parse '{value}' as chrono::Duration: {e}").into(),
1395 )
1396 })?;
1397 Ok(Self::seconds(secs))
1398 }
1399
1400 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
1401 let millis: i64 = format!("{:.0}", value * 1000.0).parse().map_err(|e| {
1402 DrizzleError::ConversionError(
1403 format!("cannot convert REAL {value} to chrono::Duration: {e}").into(),
1404 )
1405 })?;
1406 Ok(Self::milliseconds(millis))
1407 }
1408
1409 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1410 Err(DrizzleError::ConversionError(
1411 "cannot convert BLOB to chrono::Duration".into(),
1412 ))
1413 }
1414}
1415
1416#[cfg(feature = "time")]
1417impl FromSQLiteValue for time::Duration {
1418 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
1419 Ok(Self::seconds(value))
1420 }
1421
1422 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1423 let secs: i64 = value.trim_end_matches('s').parse().map_err(|e| {
1425 DrizzleError::ConversionError(
1426 format!("cannot parse '{value}' as time::Duration: {e}").into(),
1427 )
1428 })?;
1429 Ok(Self::seconds(secs))
1430 }
1431
1432 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
1433 Ok(Self::seconds_f64(value))
1434 }
1435
1436 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1437 Err(DrizzleError::ConversionError(
1438 "cannot convert BLOB to time::Duration".into(),
1439 ))
1440 }
1441}
1442
1443#[cfg(feature = "serde")]
1448impl FromSQLiteValue for serde_json::Value {
1449 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
1450 Ok(Self::Number(value.into()))
1451 }
1452
1453 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1454 serde_json::from_str(value).map_err(|e| {
1455 DrizzleError::ConversionError(format!("cannot parse '{value}' as JSON: {e}").into())
1456 })
1457 }
1458
1459 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
1460 serde_json::Number::from_f64(value)
1461 .map(serde_json::Value::Number)
1462 .ok_or_else(|| {
1463 DrizzleError::ConversionError(
1464 format!("cannot convert non-finite REAL {value} to JSON").into(),
1465 )
1466 })
1467 }
1468
1469 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
1470 serde_json::from_slice(value).map_err(|e| {
1471 DrizzleError::ConversionError(format!("cannot parse BLOB as JSON: {e}").into())
1472 })
1473 }
1474}
1475
1476#[cfg(feature = "arrayvec")]
1481impl<const N: usize> FromSQLiteValue for arrayvec::ArrayString<N> {
1482 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
1483 let s = value.to_string();
1484 Self::from(&s).map_err(|_| {
1485 DrizzleError::ConversionError(
1486 format!(
1487 "String length {} exceeds ArrayString capacity {}",
1488 s.len(),
1489 N
1490 )
1491 .into(),
1492 )
1493 })
1494 }
1495
1496 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1497 Self::from(value).map_err(|_| {
1498 DrizzleError::ConversionError(
1499 format!(
1500 "Text length {} exceeds ArrayString capacity {}",
1501 value.len(),
1502 N
1503 )
1504 .into(),
1505 )
1506 })
1507 }
1508
1509 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
1510 let s = value.to_string();
1511 Self::from(&s).map_err(|_| {
1512 DrizzleError::ConversionError(
1513 format!(
1514 "String length {} exceeds ArrayString capacity {}",
1515 s.len(),
1516 N
1517 )
1518 .into(),
1519 )
1520 })
1521 }
1522
1523 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
1524 let s = String::from_utf8(value.to_vec())
1525 .map_err(|e| DrizzleError::ConversionError(format!("invalid UTF-8: {e}").into()))?;
1526 Self::from(&s).map_err(|_| {
1527 DrizzleError::ConversionError(
1528 format!(
1529 "String length {} exceeds ArrayString capacity {}",
1530 s.len(),
1531 N
1532 )
1533 .into(),
1534 )
1535 })
1536 }
1537}
1538
1539#[cfg(feature = "arrayvec")]
1540impl<const N: usize> FromSQLiteValue for arrayvec::ArrayVec<u8, N> {
1541 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1542 Err(DrizzleError::ConversionError(
1543 "cannot convert INTEGER to ArrayVec<u8>, use BLOB".into(),
1544 ))
1545 }
1546
1547 fn from_sqlite_text(_value: &str) -> Result<Self, DrizzleError> {
1548 Err(DrizzleError::ConversionError(
1549 "cannot convert TEXT to ArrayVec<u8>, use BLOB".into(),
1550 ))
1551 }
1552
1553 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1554 Err(DrizzleError::ConversionError(
1555 "cannot convert REAL to ArrayVec<u8>, use BLOB".into(),
1556 ))
1557 }
1558
1559 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
1560 Self::try_from(value).map_err(|_| {
1561 DrizzleError::ConversionError(
1562 format!(
1563 "Blob length {} exceeds ArrayVec capacity {}",
1564 value.len(),
1565 N
1566 )
1567 .into(),
1568 )
1569 })
1570 }
1571}