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