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 value.parse().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 Self::parse_from_rfc3339(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 value.parse().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 = "time")]
1088pub(crate) mod time_text {
1089 use time::format_description::well_known::{Iso8601, Rfc3339};
1090 use time::macros::format_description;
1091
1092 pub(crate) fn time(text: &str) -> Result<time::Time, time::error::Parse> {
1095 let text = text.strip_prefix('T').unwrap_or(text);
1096 time::Time::parse(
1097 text,
1098 format_description!("[hour]:[minute]:[second].[subsecond]"),
1099 )
1100 .or_else(|_| time::Time::parse(text, format_description!("[hour]:[minute]:[second]")))
1101 }
1102
1103 pub(crate) fn primitive(text: &str) -> Result<time::PrimitiveDateTime, time::error::Parse> {
1105 time::PrimitiveDateTime::parse(text, &Iso8601::DATE_TIME)
1106 .or_else(|_| {
1107 time::PrimitiveDateTime::parse(
1108 text,
1109 format_description!(
1110 "[year]-[month]-[day] [hour]:[minute]:[second].[subsecond]"
1111 ),
1112 )
1113 })
1114 .or_else(|_| {
1115 time::PrimitiveDateTime::parse(
1116 text,
1117 format_description!("[year]-[month]-[day] [hour]:[minute]:[second]"),
1118 )
1119 })
1120 }
1121
1122 pub(crate) fn offset(text: &str) -> Result<time::OffsetDateTime, time::error::Parse> {
1124 time::OffsetDateTime::parse(text, &Rfc3339).or_else(|error| {
1125 primitive(text)
1126 .map(time::PrimitiveDateTime::assume_utc)
1127 .map_err(|_| error)
1128 })
1129 }
1130}
1131
1132#[cfg(feature = "time")]
1133impl FromSQLiteValue for time::Date {
1134 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1135 Err(DrizzleError::ConversionError(
1136 "cannot convert INTEGER to time::Date".into(),
1137 ))
1138 }
1139
1140 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1141 Self::parse(value, &time::format_description::well_known::Iso8601::DATE).map_err(|e| {
1142 DrizzleError::ConversionError(
1143 format!("cannot parse '{value}' as time::Date: {e}").into(),
1144 )
1145 })
1146 }
1147
1148 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1149 Err(DrizzleError::ConversionError(
1150 "cannot convert REAL to time::Date".into(),
1151 ))
1152 }
1153
1154 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1155 Err(DrizzleError::ConversionError(
1156 "cannot convert BLOB to time::Date".into(),
1157 ))
1158 }
1159}
1160
1161#[cfg(feature = "time")]
1162impl FromSQLiteValue for time::Time {
1163 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1164 Err(DrizzleError::ConversionError(
1165 "cannot convert INTEGER to time::Time".into(),
1166 ))
1167 }
1168
1169 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1170 time_text::time(value).map_err(|e| {
1171 DrizzleError::ConversionError(
1172 format!("cannot parse '{value}' as time::Time: {e}").into(),
1173 )
1174 })
1175 }
1176
1177 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1178 Err(DrizzleError::ConversionError(
1179 "cannot convert REAL to time::Time".into(),
1180 ))
1181 }
1182
1183 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1184 Err(DrizzleError::ConversionError(
1185 "cannot convert BLOB to time::Time".into(),
1186 ))
1187 }
1188}
1189
1190#[cfg(feature = "time")]
1191impl FromSQLiteValue for time::PrimitiveDateTime {
1192 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1193 Err(DrizzleError::ConversionError(
1194 "cannot convert INTEGER to time::PrimitiveDateTime".into(),
1195 ))
1196 }
1197
1198 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1199 time_text::primitive(value).map_err(|e| {
1200 DrizzleError::ConversionError(
1201 format!("cannot parse '{value}' as time::PrimitiveDateTime: {e}").into(),
1202 )
1203 })
1204 }
1205
1206 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1207 Err(DrizzleError::ConversionError(
1208 "cannot convert REAL to time::PrimitiveDateTime".into(),
1209 ))
1210 }
1211
1212 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1213 Err(DrizzleError::ConversionError(
1214 "cannot convert BLOB to time::PrimitiveDateTime".into(),
1215 ))
1216 }
1217}
1218
1219#[cfg(feature = "time")]
1220impl FromSQLiteValue for time::OffsetDateTime {
1221 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1222 Err(DrizzleError::ConversionError(
1223 "cannot convert INTEGER to time::OffsetDateTime".into(),
1224 ))
1225 }
1226
1227 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1228 time_text::offset(value).map_err(|e| {
1229 DrizzleError::ConversionError(
1230 format!("cannot parse '{value}' as time::OffsetDateTime: {e}").into(),
1231 )
1232 })
1233 }
1234
1235 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1236 Err(DrizzleError::ConversionError(
1237 "cannot convert REAL to time::OffsetDateTime".into(),
1238 ))
1239 }
1240
1241 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1242 Err(DrizzleError::ConversionError(
1243 "cannot convert BLOB to time::OffsetDateTime".into(),
1244 ))
1245 }
1246}
1247
1248#[cfg(feature = "jiff")]
1254fn parse_jiff<T: core::str::FromStr<Err = jiff::Error>>(
1255 value: &str,
1256 name: &str,
1257) -> Result<T, DrizzleError> {
1258 value.parse().map_err(|e: jiff::Error| {
1259 DrizzleError::ConversionError(format!("cannot parse '{value}' as {name}: {e}").into())
1260 })
1261}
1262
1263#[cfg(feature = "jiff")]
1265macro_rules! impl_from_sqlite_value_jiff {
1266 ($($ty:ty => $name:literal, $parse:expr;)+) => {$(
1267 impl FromSQLiteValue for $ty {
1268 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1269 Err(DrizzleError::ConversionError(
1270 concat!("cannot convert INTEGER to ", $name).into(),
1271 ))
1272 }
1273
1274 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1275 $parse(value)
1276 }
1277
1278 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1279 Err(DrizzleError::ConversionError(
1280 concat!("cannot convert REAL to ", $name).into(),
1281 ))
1282 }
1283
1284 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1285 Err(DrizzleError::ConversionError(
1286 concat!("cannot convert BLOB to ", $name).into(),
1287 ))
1288 }
1289 }
1290 )+};
1291}
1292
1293#[cfg(feature = "jiff")]
1294impl_from_sqlite_value_jiff! {
1295 jiff::civil::Date => "jiff::civil::Date",
1296 |value| parse_jiff(value, "jiff::civil::Date");
1297 jiff::civil::Time => "jiff::civil::Time",
1298 |value| parse_jiff(value, "jiff::civil::Time");
1299 jiff::civil::DateTime => "jiff::civil::DateTime",
1300 |value| parse_jiff(value, "jiff::civil::DateTime");
1301 jiff::Timestamp => "jiff::Timestamp", |value: &str| {
1304 value.parse().or_else(|_| {
1305 let civil: jiff::civil::DateTime = parse_jiff(value, "jiff::Timestamp")?;
1306 jiff::tz::Offset::UTC.to_timestamp(civil).map_err(|e| {
1307 DrizzleError::ConversionError(
1308 format!("cannot convert '{value}' to jiff::Timestamp: {e}").into(),
1309 )
1310 })
1311 })
1312 };
1313}
1314
1315#[cfg(feature = "rust-decimal")]
1320impl FromSQLiteValue for rust_decimal::Decimal {
1321 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
1322 Ok(Self::from(value))
1323 }
1324
1325 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1326 value.parse().map_err(|e| {
1327 DrizzleError::ConversionError(format!("cannot parse '{value}' as Decimal: {e}").into())
1328 })
1329 }
1330
1331 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
1332 Self::try_from(value).map_err(|e| {
1333 DrizzleError::ConversionError(
1334 format!("cannot convert REAL {value} to Decimal: {e}").into(),
1335 )
1336 })
1337 }
1338
1339 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1340 Err(DrizzleError::ConversionError(
1341 "cannot convert BLOB to Decimal".into(),
1342 ))
1343 }
1344}
1345
1346#[cfg(feature = "chrono")]
1351impl FromSQLiteValue for chrono::Duration {
1352 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
1353 Ok(Self::seconds(value))
1354 }
1355
1356 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1357 let secs: i64 = value.trim_end_matches('s').parse().map_err(|e| {
1359 DrizzleError::ConversionError(
1360 format!("cannot parse '{value}' as chrono::Duration: {e}").into(),
1361 )
1362 })?;
1363 Ok(Self::seconds(secs))
1364 }
1365
1366 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
1367 let millis: i64 = format!("{:.0}", value * 1000.0).parse().map_err(|e| {
1368 DrizzleError::ConversionError(
1369 format!("cannot convert REAL {value} to chrono::Duration: {e}").into(),
1370 )
1371 })?;
1372 Ok(Self::milliseconds(millis))
1373 }
1374
1375 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1376 Err(DrizzleError::ConversionError(
1377 "cannot convert BLOB to chrono::Duration".into(),
1378 ))
1379 }
1380}
1381
1382#[cfg(feature = "time")]
1383impl FromSQLiteValue for time::Duration {
1384 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
1385 Ok(Self::seconds(value))
1386 }
1387
1388 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1389 let secs: i64 = value.trim_end_matches('s').parse().map_err(|e| {
1391 DrizzleError::ConversionError(
1392 format!("cannot parse '{value}' as time::Duration: {e}").into(),
1393 )
1394 })?;
1395 Ok(Self::seconds(secs))
1396 }
1397
1398 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
1399 Ok(Self::seconds_f64(value))
1400 }
1401
1402 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1403 Err(DrizzleError::ConversionError(
1404 "cannot convert BLOB to time::Duration".into(),
1405 ))
1406 }
1407}
1408
1409#[cfg(feature = "serde")]
1414impl FromSQLiteValue for serde_json::Value {
1415 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
1416 Ok(Self::Number(value.into()))
1417 }
1418
1419 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1420 serde_json::from_str(value).map_err(|e| {
1421 DrizzleError::ConversionError(format!("cannot parse '{value}' as JSON: {e}").into())
1422 })
1423 }
1424
1425 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
1426 serde_json::Number::from_f64(value)
1427 .map(serde_json::Value::Number)
1428 .ok_or_else(|| {
1429 DrizzleError::ConversionError(
1430 format!("cannot convert non-finite REAL {value} to JSON").into(),
1431 )
1432 })
1433 }
1434
1435 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
1436 serde_json::from_slice(value).map_err(|e| {
1437 DrizzleError::ConversionError(format!("cannot parse BLOB as JSON: {e}").into())
1438 })
1439 }
1440}
1441
1442#[cfg(feature = "arrayvec")]
1447impl<const N: usize> FromSQLiteValue for arrayvec::ArrayString<N> {
1448 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
1449 let s = value.to_string();
1450 Self::from(&s).map_err(|_| {
1451 DrizzleError::ConversionError(
1452 format!(
1453 "String length {} exceeds ArrayString capacity {}",
1454 s.len(),
1455 N
1456 )
1457 .into(),
1458 )
1459 })
1460 }
1461
1462 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1463 Self::from(value).map_err(|_| {
1464 DrizzleError::ConversionError(
1465 format!(
1466 "Text length {} exceeds ArrayString capacity {}",
1467 value.len(),
1468 N
1469 )
1470 .into(),
1471 )
1472 })
1473 }
1474
1475 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
1476 let s = value.to_string();
1477 Self::from(&s).map_err(|_| {
1478 DrizzleError::ConversionError(
1479 format!(
1480 "String length {} exceeds ArrayString capacity {}",
1481 s.len(),
1482 N
1483 )
1484 .into(),
1485 )
1486 })
1487 }
1488
1489 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
1490 let s = String::from_utf8(value.to_vec())
1491 .map_err(|e| DrizzleError::ConversionError(format!("invalid UTF-8: {e}").into()))?;
1492 Self::from(&s).map_err(|_| {
1493 DrizzleError::ConversionError(
1494 format!(
1495 "String length {} exceeds ArrayString capacity {}",
1496 s.len(),
1497 N
1498 )
1499 .into(),
1500 )
1501 })
1502 }
1503}
1504
1505#[cfg(feature = "arrayvec")]
1506impl<const N: usize> FromSQLiteValue for arrayvec::ArrayVec<u8, N> {
1507 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1508 Err(DrizzleError::ConversionError(
1509 "cannot convert INTEGER to ArrayVec<u8>, use BLOB".into(),
1510 ))
1511 }
1512
1513 fn from_sqlite_text(_value: &str) -> Result<Self, DrizzleError> {
1514 Err(DrizzleError::ConversionError(
1515 "cannot convert TEXT to ArrayVec<u8>, use BLOB".into(),
1516 ))
1517 }
1518
1519 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1520 Err(DrizzleError::ConversionError(
1521 "cannot convert REAL to ArrayVec<u8>, use BLOB".into(),
1522 ))
1523 }
1524
1525 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
1526 Self::try_from(value).map_err(|_| {
1527 DrizzleError::ConversionError(
1528 format!(
1529 "Blob length {} exceeds ArrayVec capacity {}",
1530 value.len(),
1531 N
1532 )
1533 .into(),
1534 )
1535 })
1536 }
1537}