Skip to main content

drizzle_sqlite/values/
conversions.rs

1//! From and `TryFrom` implementations for `SQLiteValue`
2
3use super::{OwnedSQLiteValue, SQLiteValue};
4use crate::prelude::*;
5use drizzle_core::{error::DrizzleError, sql::SQL, traits::ToSQL};
6
7#[cfg(feature = "uuid")]
8use uuid::Uuid;
9
10//------------------------------------------------------------------------------
11// ToSQL Implementation
12//------------------------------------------------------------------------------
13
14impl<'a> ToSQL<'a, Self> for SQLiteValue<'a> {
15    fn to_sql(&self) -> SQL<'a, Self> {
16        SQL::param(self.clone())
17    }
18}
19
20//------------------------------------------------------------------------------
21// From OwnedSQLiteValue
22//------------------------------------------------------------------------------
23
24impl From<OwnedSQLiteValue> for SQLiteValue<'_> {
25    fn from(value: OwnedSQLiteValue) -> Self {
26        match value {
27            OwnedSQLiteValue::Integer(f) => SQLiteValue::Integer(f),
28            OwnedSQLiteValue::Real(r) => SQLiteValue::Real(r),
29            OwnedSQLiteValue::Text(v) => SQLiteValue::Text(Cow::Owned(v)),
30            OwnedSQLiteValue::Blob(v) => SQLiteValue::Blob(Cow::Owned(v.into())),
31            OwnedSQLiteValue::Null => SQLiteValue::Null,
32        }
33    }
34}
35
36impl<'a> From<&'a OwnedSQLiteValue> for SQLiteValue<'a> {
37    fn from(value: &'a OwnedSQLiteValue) -> Self {
38        match value {
39            OwnedSQLiteValue::Integer(f) => SQLiteValue::Integer(*f),
40            OwnedSQLiteValue::Real(r) => SQLiteValue::Real(*r),
41            OwnedSQLiteValue::Text(v) => SQLiteValue::Text(Cow::Borrowed(v)),
42            OwnedSQLiteValue::Blob(v) => SQLiteValue::Blob(Cow::Borrowed(v)),
43            OwnedSQLiteValue::Null => SQLiteValue::Null,
44        }
45    }
46}
47
48impl<'a> From<&'a Self> for SQLiteValue<'a> {
49    fn from(value: &'a Self) -> Self {
50        match value {
51            SQLiteValue::Integer(f) => SQLiteValue::Integer(*f),
52            SQLiteValue::Real(r) => SQLiteValue::Real(*r),
53            SQLiteValue::Text(v) => SQLiteValue::Text(Cow::Borrowed(v)),
54            SQLiteValue::Blob(v) => SQLiteValue::Blob(Cow::Borrowed(v)),
55            SQLiteValue::Null => SQLiteValue::Null,
56        }
57    }
58}
59
60impl<'a> From<Cow<'a, Self>> for SQLiteValue<'a> {
61    fn from(value: Cow<'a, Self>) -> Self {
62        match value {
63            Cow::Borrowed(r) => r.into(),
64            Cow::Owned(o) => o,
65        }
66    }
67}
68
69impl<'a> From<&'a Cow<'a, Self>> for SQLiteValue<'a> {
70    fn from(value: &'a Cow<'a, Self>) -> Self {
71        match value {
72            Cow::Borrowed(r) => (*r).into(),
73            Cow::Owned(o) => o.into(),
74        }
75    }
76}
77
78//------------------------------------------------------------------------------
79// From<T> implementations
80// Macro-based to reduce boilerplate
81//------------------------------------------------------------------------------
82
83/// Integer widths where `i64::from(T)` is infallible.
84macro_rules! impl_from_lossless_int_for_sqlite_value {
85    ($($ty:ty),* $(,)?) => {
86        $(
87            impl<'a> From<$ty> for SQLiteValue<'a> {
88                #[inline]
89                fn from(value: $ty) -> Self {
90                    SQLiteValue::Integer(i64::from(value))
91                }
92            }
93
94            impl<'a> From<&$ty> for SQLiteValue<'a> {
95                #[inline]
96                fn from(value: &$ty) -> Self {
97                    SQLiteValue::Integer(i64::from(*value))
98                }
99            }
100        )*
101    };
102}
103
104// Types that widen to i64 without loss.
105impl_from_lossless_int_for_sqlite_value!(i8, i16, i32, u8, u16, u32, bool);
106
107// i64 identity — no conversion needed.
108impl From<i64> for SQLiteValue<'_> {
109    #[inline]
110    fn from(value: i64) -> Self {
111        SQLiteValue::Integer(value)
112    }
113}
114
115impl From<&i64> for SQLiteValue<'_> {
116    #[inline]
117    fn from(value: &i64) -> Self {
118        SQLiteValue::Integer(*value)
119    }
120}
121
122// u64 → i64 by reinterpreting bits. SQLite stores INTEGER as signed 64-bit;
123// this matches the round-trip convention used by the matching `i64 → u64`
124// reinterpretation on read.
125impl From<u64> for SQLiteValue<'_> {
126    #[inline]
127    fn from(value: u64) -> Self {
128        SQLiteValue::Integer(value.cast_signed())
129    }
130}
131
132impl From<&u64> for SQLiteValue<'_> {
133    #[inline]
134    fn from(value: &u64) -> Self {
135        SQLiteValue::Integer(value.cast_signed())
136    }
137}
138
139/// Pointer-sized integer widths (usize/isize). All Rust-supported targets have
140/// pointers ≤ 64 bits, so `i64::try_from` succeeds; the saturating fallback is
141/// defensive only.
142macro_rules! impl_from_pointer_int_for_sqlite_value {
143    ($($ty:ty),* $(,)?) => {
144        $(
145            impl<'a> From<$ty> for SQLiteValue<'a> {
146                #[inline]
147                fn from(value: $ty) -> Self {
148                    SQLiteValue::Integer(i64::try_from(value).unwrap_or(i64::MAX))
149                }
150            }
151
152            impl<'a> From<&$ty> for SQLiteValue<'a> {
153                #[inline]
154                fn from(value: &$ty) -> Self {
155                    SQLiteValue::Integer(i64::try_from(*value).unwrap_or(i64::MAX))
156                }
157            }
158        )*
159    };
160}
161
162impl_from_pointer_int_for_sqlite_value!(isize, usize);
163
164// f32 widens exactly into f64.
165impl From<f32> for SQLiteValue<'_> {
166    #[inline]
167    fn from(value: f32) -> Self {
168        SQLiteValue::Real(f64::from(value))
169    }
170}
171
172impl From<&f32> for SQLiteValue<'_> {
173    #[inline]
174    fn from(value: &f32) -> Self {
175        SQLiteValue::Real(f64::from(*value))
176    }
177}
178
179// f64 identity.
180impl From<f64> for SQLiteValue<'_> {
181    #[inline]
182    fn from(value: f64) -> Self {
183        SQLiteValue::Real(value)
184    }
185}
186
187impl From<&f64> for SQLiteValue<'_> {
188    #[inline]
189    fn from(value: &f64) -> Self {
190        SQLiteValue::Real(*value)
191    }
192}
193
194// --- String Types ---
195
196impl<'a> From<&'a str> for SQLiteValue<'a> {
197    fn from(value: &'a str) -> Self {
198        SQLiteValue::Text(Cow::Borrowed(value))
199    }
200}
201
202impl<'a> From<Cow<'a, str>> for SQLiteValue<'a> {
203    fn from(value: Cow<'a, str>) -> Self {
204        SQLiteValue::Text(value)
205    }
206}
207
208impl From<String> for SQLiteValue<'_> {
209    fn from(value: String) -> Self {
210        SQLiteValue::Text(Cow::Owned(value))
211    }
212}
213
214impl<'a> From<&'a String> for SQLiteValue<'a> {
215    fn from(value: &'a String) -> Self {
216        SQLiteValue::Text(Cow::Borrowed(value))
217    }
218}
219
220impl From<Box<String>> for SQLiteValue<'_> {
221    fn from(value: Box<String>) -> Self {
222        SQLiteValue::Text(Cow::Owned(*value))
223    }
224}
225
226impl<'a> From<&'a Box<String>> for SQLiteValue<'a> {
227    fn from(value: &'a Box<String>) -> Self {
228        SQLiteValue::Text(Cow::Borrowed(value.as_str()))
229    }
230}
231
232impl From<Rc<String>> for SQLiteValue<'_> {
233    fn from(value: Rc<String>) -> Self {
234        SQLiteValue::Text(Cow::Owned(value.as_ref().clone()))
235    }
236}
237
238impl<'a> From<&'a Rc<String>> for SQLiteValue<'a> {
239    fn from(value: &'a Rc<String>) -> Self {
240        SQLiteValue::Text(Cow::Borrowed(value.as_str()))
241    }
242}
243
244impl From<Arc<String>> for SQLiteValue<'_> {
245    fn from(value: Arc<String>) -> Self {
246        SQLiteValue::Text(Cow::Owned(value.as_ref().clone()))
247    }
248}
249
250impl<'a> From<&'a Arc<String>> for SQLiteValue<'a> {
251    fn from(value: &'a Arc<String>) -> Self {
252        SQLiteValue::Text(Cow::Borrowed(value.as_str()))
253    }
254}
255
256impl From<Box<str>> for SQLiteValue<'_> {
257    fn from(value: Box<str>) -> Self {
258        SQLiteValue::Text(Cow::Owned(value.into()))
259    }
260}
261
262impl<'a> From<&'a Box<str>> for SQLiteValue<'a> {
263    fn from(value: &'a Box<str>) -> Self {
264        SQLiteValue::Text(Cow::Borrowed(value.as_ref()))
265    }
266}
267
268impl From<Rc<str>> for SQLiteValue<'_> {
269    fn from(value: Rc<str>) -> Self {
270        SQLiteValue::Text(Cow::Owned(value.as_ref().to_string()))
271    }
272}
273
274impl<'a> From<&'a Rc<str>> for SQLiteValue<'a> {
275    fn from(value: &'a Rc<str>) -> Self {
276        SQLiteValue::Text(Cow::Borrowed(value.as_ref()))
277    }
278}
279
280impl From<Arc<str>> for SQLiteValue<'_> {
281    fn from(value: Arc<str>) -> Self {
282        SQLiteValue::Text(Cow::Owned(value.as_ref().to_string()))
283    }
284}
285
286impl<'a> From<&'a Arc<str>> for SQLiteValue<'a> {
287    fn from(value: &'a Arc<str>) -> Self {
288        SQLiteValue::Text(Cow::Borrowed(value.as_ref()))
289    }
290}
291
292// --- ArrayString ---
293
294#[cfg(feature = "arrayvec")]
295impl<const N: usize> From<arrayvec::ArrayString<N>> for SQLiteValue<'_> {
296    fn from(value: arrayvec::ArrayString<N>) -> Self {
297        SQLiteValue::Text(Cow::Owned(value.to_string()))
298    }
299}
300
301#[cfg(feature = "arrayvec")]
302impl<const N: usize> From<&arrayvec::ArrayString<N>> for SQLiteValue<'_> {
303    fn from(value: &arrayvec::ArrayString<N>) -> Self {
304        SQLiteValue::Text(Cow::Owned(String::from(value.as_str())))
305    }
306}
307
308impl From<compact_str::CompactString> for SQLiteValue<'_> {
309    fn from(value: compact_str::CompactString) -> Self {
310        SQLiteValue::Text(Cow::Owned(value.to_string()))
311    }
312}
313
314impl<'a> From<&'a compact_str::CompactString> for SQLiteValue<'a> {
315    fn from(value: &'a compact_str::CompactString) -> Self {
316        SQLiteValue::Text(Cow::Borrowed(value.as_str()))
317    }
318}
319
320// --- Binary Data ---
321
322impl<'a> From<&'a [u8]> for SQLiteValue<'a> {
323    fn from(value: &'a [u8]) -> Self {
324        SQLiteValue::Blob(Cow::Borrowed(value))
325    }
326}
327
328impl<'a> From<Cow<'a, [u8]>> for SQLiteValue<'a> {
329    fn from(value: Cow<'a, [u8]>) -> Self {
330        SQLiteValue::Blob(value)
331    }
332}
333
334impl From<Vec<u8>> for SQLiteValue<'_> {
335    fn from(value: Vec<u8>) -> Self {
336        SQLiteValue::Blob(Cow::Owned(value))
337    }
338}
339
340impl From<Box<Vec<u8>>> for SQLiteValue<'_> {
341    fn from(value: Box<Vec<u8>>) -> Self {
342        SQLiteValue::Blob(Cow::Owned(*value))
343    }
344}
345
346impl<'a> From<&'a Box<Vec<u8>>> for SQLiteValue<'a> {
347    fn from(value: &'a Box<Vec<u8>>) -> Self {
348        SQLiteValue::Blob(Cow::Borrowed(value.as_slice()))
349    }
350}
351
352impl From<Rc<Vec<u8>>> for SQLiteValue<'_> {
353    fn from(value: Rc<Vec<u8>>) -> Self {
354        SQLiteValue::Blob(Cow::Owned(value.as_ref().clone()))
355    }
356}
357
358impl<'a> From<&'a Rc<Vec<u8>>> for SQLiteValue<'a> {
359    fn from(value: &'a Rc<Vec<u8>>) -> Self {
360        SQLiteValue::Blob(Cow::Borrowed(value.as_slice()))
361    }
362}
363
364impl From<Arc<Vec<u8>>> for SQLiteValue<'_> {
365    fn from(value: Arc<Vec<u8>>) -> Self {
366        SQLiteValue::Blob(Cow::Owned(value.as_ref().clone()))
367    }
368}
369
370impl<'a> From<&'a Arc<Vec<u8>>> for SQLiteValue<'a> {
371    fn from(value: &'a Arc<Vec<u8>>) -> Self {
372        SQLiteValue::Blob(Cow::Borrowed(value.as_slice()))
373    }
374}
375
376// --- ArrayVec<u8, N> ---
377
378#[cfg(feature = "arrayvec")]
379impl<const N: usize> From<arrayvec::ArrayVec<u8, N>> for SQLiteValue<'_> {
380    fn from(value: arrayvec::ArrayVec<u8, N>) -> Self {
381        SQLiteValue::Blob(Cow::Owned(value.to_vec()))
382    }
383}
384
385#[cfg(feature = "arrayvec")]
386impl<const N: usize> From<&arrayvec::ArrayVec<u8, N>> for SQLiteValue<'_> {
387    fn from(value: &arrayvec::ArrayVec<u8, N>) -> Self {
388        SQLiteValue::Blob(Cow::Owned(value.to_vec()))
389    }
390}
391
392#[cfg(feature = "bytes")]
393impl From<bytes::Bytes> for SQLiteValue<'_> {
394    fn from(value: bytes::Bytes) -> Self {
395        SQLiteValue::Blob(Cow::Owned(value.to_vec()))
396    }
397}
398
399#[cfg(feature = "bytes")]
400impl<'a> From<&'a bytes::Bytes> for SQLiteValue<'a> {
401    fn from(value: &'a bytes::Bytes) -> Self {
402        SQLiteValue::Blob(Cow::Owned(value.to_vec()))
403    }
404}
405
406#[cfg(feature = "bytes")]
407impl From<bytes::BytesMut> for SQLiteValue<'_> {
408    fn from(value: bytes::BytesMut) -> Self {
409        SQLiteValue::Blob(Cow::Owned(value.to_vec()))
410    }
411}
412
413#[cfg(feature = "bytes")]
414impl<'a> From<&'a bytes::BytesMut> for SQLiteValue<'a> {
415    fn from(value: &'a bytes::BytesMut) -> Self {
416        SQLiteValue::Blob(Cow::Owned(value.to_vec()))
417    }
418}
419
420#[cfg(feature = "smallvec")]
421impl<const N: usize> From<smallvec::SmallVec<[u8; N]>> for SQLiteValue<'_> {
422    fn from(value: smallvec::SmallVec<[u8; N]>) -> Self {
423        SQLiteValue::Blob(Cow::Owned(value.into_vec()))
424    }
425}
426
427#[cfg(feature = "smallvec")]
428impl<const N: usize> From<&smallvec::SmallVec<[u8; N]>> for SQLiteValue<'_> {
429    fn from(value: &smallvec::SmallVec<[u8; N]>) -> Self {
430        SQLiteValue::Blob(Cow::Owned(value.to_vec()))
431    }
432}
433
434// --- Chrono Date/Time Types (stored as ISO-8601 text) ---
435
436#[cfg(feature = "chrono")]
437impl From<chrono::NaiveDate> for SQLiteValue<'_> {
438    fn from(value: chrono::NaiveDate) -> Self {
439        SQLiteValue::Text(Cow::Owned(value.to_string()))
440    }
441}
442
443#[cfg(feature = "chrono")]
444impl From<&chrono::NaiveDate> for SQLiteValue<'_> {
445    fn from(value: &chrono::NaiveDate) -> Self {
446        SQLiteValue::Text(Cow::Owned(value.to_string()))
447    }
448}
449
450#[cfg(feature = "chrono")]
451impl From<chrono::NaiveTime> for SQLiteValue<'_> {
452    fn from(value: chrono::NaiveTime) -> Self {
453        SQLiteValue::Text(Cow::Owned(value.to_string()))
454    }
455}
456
457#[cfg(feature = "chrono")]
458impl From<&chrono::NaiveTime> for SQLiteValue<'_> {
459    fn from(value: &chrono::NaiveTime) -> Self {
460        SQLiteValue::Text(Cow::Owned(value.to_string()))
461    }
462}
463
464#[cfg(feature = "chrono")]
465impl From<chrono::NaiveDateTime> for SQLiteValue<'_> {
466    fn from(value: chrono::NaiveDateTime) -> Self {
467        SQLiteValue::Text(Cow::Owned(value.to_string()))
468    }
469}
470
471#[cfg(feature = "chrono")]
472impl From<&chrono::NaiveDateTime> for SQLiteValue<'_> {
473    fn from(value: &chrono::NaiveDateTime) -> Self {
474        SQLiteValue::Text(Cow::Owned(value.to_string()))
475    }
476}
477
478#[cfg(feature = "chrono")]
479impl From<chrono::DateTime<chrono::FixedOffset>> for SQLiteValue<'_> {
480    fn from(value: chrono::DateTime<chrono::FixedOffset>) -> Self {
481        SQLiteValue::Text(Cow::Owned(value.to_rfc3339()))
482    }
483}
484
485#[cfg(feature = "chrono")]
486impl From<&chrono::DateTime<chrono::FixedOffset>> for SQLiteValue<'_> {
487    fn from(value: &chrono::DateTime<chrono::FixedOffset>) -> Self {
488        SQLiteValue::Text(Cow::Owned(value.to_rfc3339()))
489    }
490}
491
492#[cfg(feature = "chrono")]
493impl From<chrono::DateTime<chrono::Utc>> for SQLiteValue<'_> {
494    fn from(value: chrono::DateTime<chrono::Utc>) -> Self {
495        SQLiteValue::Text(Cow::Owned(value.to_rfc3339()))
496    }
497}
498
499#[cfg(feature = "chrono")]
500impl From<&chrono::DateTime<chrono::Utc>> for SQLiteValue<'_> {
501    fn from(value: &chrono::DateTime<chrono::Utc>) -> Self {
502        SQLiteValue::Text(Cow::Owned(value.to_rfc3339()))
503    }
504}
505
506#[cfg(feature = "chrono")]
507impl From<chrono::Duration> for SQLiteValue<'_> {
508    fn from(value: chrono::Duration) -> Self {
509        SQLiteValue::from(&value)
510    }
511}
512
513#[cfg(feature = "chrono")]
514impl From<&chrono::Duration> for SQLiteValue<'_> {
515    fn from(value: &chrono::Duration) -> Self {
516        let abs = value.abs();
517        SQLiteValue::Text(Cow::Owned(super::duration::format(
518            *value < chrono::Duration::zero(),
519            abs.num_seconds().unsigned_abs(),
520            abs.subsec_nanos().unsigned_abs(),
521        )))
522    }
523}
524
525// --- Time crate Date/Time Types (stored as ISO-8601 text) ---
526
527#[cfg(feature = "time")]
528impl From<time::Date> for SQLiteValue<'_> {
529    fn from(value: time::Date) -> Self {
530        SQLiteValue::Text(Cow::Owned(
531            value
532                .format(&time::format_description::well_known::Iso8601::DATE)
533                .unwrap_or_else(|_| value.to_string()),
534        ))
535    }
536}
537
538#[cfg(feature = "time")]
539impl From<&time::Date> for SQLiteValue<'_> {
540    fn from(value: &time::Date) -> Self {
541        SQLiteValue::Text(Cow::Owned(
542            value
543                .format(&time::format_description::well_known::Iso8601::DATE)
544                .unwrap_or_else(|_| value.to_string()),
545        ))
546    }
547}
548
549/// `HH:MM:SS.fraction`, as SQLite's time functions read it. (ISO 8601's
550/// time-only format starts with a `T`, which they reject.)
551#[cfg(feature = "time")]
552impl From<time::Time> for SQLiteValue<'_> {
553    fn from(value: time::Time) -> Self {
554        SQLiteValue::Text(Cow::Owned(
555            value
556                .format(time::macros::format_description!(
557                    "[hour]:[minute]:[second].[subsecond]"
558                ))
559                .unwrap_or_else(|_| value.to_string()),
560        ))
561    }
562}
563
564#[cfg(feature = "time")]
565impl From<&time::Time> for SQLiteValue<'_> {
566    fn from(value: &time::Time) -> Self {
567        Self::from(*value)
568    }
569}
570
571#[cfg(feature = "time")]
572impl From<time::PrimitiveDateTime> for SQLiteValue<'_> {
573    fn from(value: time::PrimitiveDateTime) -> Self {
574        SQLiteValue::Text(Cow::Owned(
575            value
576                .format(&time::format_description::well_known::Iso8601::DATE_TIME)
577                .unwrap_or_else(|_| value.to_string()),
578        ))
579    }
580}
581
582#[cfg(feature = "time")]
583impl From<&time::PrimitiveDateTime> for SQLiteValue<'_> {
584    fn from(value: &time::PrimitiveDateTime) -> Self {
585        SQLiteValue::Text(Cow::Owned(
586            value
587                .format(&time::format_description::well_known::Iso8601::DATE_TIME)
588                .unwrap_or_else(|_| value.to_string()),
589        ))
590    }
591}
592
593#[cfg(feature = "time")]
594impl From<time::OffsetDateTime> for SQLiteValue<'_> {
595    fn from(value: time::OffsetDateTime) -> Self {
596        SQLiteValue::Text(Cow::Owned(
597            value
598                .format(&time::format_description::well_known::Rfc3339)
599                .unwrap_or_else(|_| value.to_string()),
600        ))
601    }
602}
603
604#[cfg(feature = "time")]
605impl From<&time::OffsetDateTime> for SQLiteValue<'_> {
606    fn from(value: &time::OffsetDateTime) -> Self {
607        SQLiteValue::Text(Cow::Owned(
608            value
609                .format(&time::format_description::well_known::Rfc3339)
610                .unwrap_or_else(|_| value.to_string()),
611        ))
612    }
613}
614
615#[cfg(feature = "time")]
616impl From<time::Duration> for SQLiteValue<'_> {
617    fn from(value: time::Duration) -> Self {
618        SQLiteValue::from(&value)
619    }
620}
621
622#[cfg(feature = "time")]
623impl From<&time::Duration> for SQLiteValue<'_> {
624    fn from(value: &time::Duration) -> Self {
625        SQLiteValue::Text(Cow::Owned(super::duration::format(
626            value.is_negative(),
627            value.whole_seconds().unsigned_abs(),
628            value.subsec_nanoseconds().unsigned_abs(),
629        )))
630    }
631}
632
633// --- jiff ---
634//
635// ISO 8601 text, as SQLite's date and time functions read it. A civil
636// datetime puts a space between date and time, as `datetime()` and
637// `CURRENT_TIMESTAMP` do; a timestamp is RFC 3339 in UTC.
638
639#[cfg(feature = "jiff")]
640impl From<jiff::civil::Date> for SQLiteValue<'_> {
641    fn from(value: jiff::civil::Date) -> Self {
642        SQLiteValue::Text(Cow::Owned(value.to_string()))
643    }
644}
645
646#[cfg(feature = "jiff")]
647impl From<&jiff::civil::Date> for SQLiteValue<'_> {
648    fn from(value: &jiff::civil::Date) -> Self {
649        Self::from(*value)
650    }
651}
652
653#[cfg(feature = "jiff")]
654impl From<jiff::civil::Time> for SQLiteValue<'_> {
655    fn from(value: jiff::civil::Time) -> Self {
656        SQLiteValue::Text(Cow::Owned(value.to_string()))
657    }
658}
659
660#[cfg(feature = "jiff")]
661impl From<&jiff::civil::Time> for SQLiteValue<'_> {
662    fn from(value: &jiff::civil::Time) -> Self {
663        Self::from(*value)
664    }
665}
666
667#[cfg(feature = "jiff")]
668impl From<jiff::civil::DateTime> for SQLiteValue<'_> {
669    fn from(value: jiff::civil::DateTime) -> Self {
670        SQLiteValue::Text(Cow::Owned(format!("{} {}", value.date(), value.time())))
671    }
672}
673
674#[cfg(feature = "jiff")]
675impl From<&jiff::civil::DateTime> for SQLiteValue<'_> {
676    fn from(value: &jiff::civil::DateTime) -> Self {
677        Self::from(*value)
678    }
679}
680
681#[cfg(feature = "jiff")]
682impl From<jiff::Timestamp> for SQLiteValue<'_> {
683    fn from(value: jiff::Timestamp) -> Self {
684        SQLiteValue::Text(Cow::Owned(value.to_string()))
685    }
686}
687
688#[cfg(feature = "jiff")]
689impl From<&jiff::Timestamp> for SQLiteValue<'_> {
690    fn from(value: &jiff::Timestamp) -> Self {
691        Self::from(*value)
692    }
693}
694
695// --- Decimal (stored as text for lossless round-trip) ---
696
697#[cfg(feature = "rust-decimal")]
698impl From<rust_decimal::Decimal> for SQLiteValue<'_> {
699    fn from(value: rust_decimal::Decimal) -> Self {
700        SQLiteValue::Text(Cow::Owned(value.to_string()))
701    }
702}
703
704#[cfg(feature = "rust-decimal")]
705impl From<&rust_decimal::Decimal> for SQLiteValue<'_> {
706    fn from(value: &rust_decimal::Decimal) -> Self {
707        SQLiteValue::Text(Cow::Owned(value.to_string()))
708    }
709}
710
711// --- JSON ---
712
713#[cfg(feature = "serde")]
714impl From<serde_json::Value> for SQLiteValue<'_> {
715    fn from(value: serde_json::Value) -> Self {
716        SQLiteValue::Text(Cow::Owned(value.to_string()))
717    }
718}
719
720#[cfg(feature = "serde")]
721impl From<&serde_json::Value> for SQLiteValue<'_> {
722    fn from(value: &serde_json::Value) -> Self {
723        SQLiteValue::Text(Cow::Owned(value.to_string()))
724    }
725}
726
727// --- UUID ---
728
729#[cfg(feature = "uuid")]
730impl From<Uuid> for SQLiteValue<'_> {
731    fn from(value: Uuid) -> Self {
732        SQLiteValue::Blob(Cow::Owned(value.as_bytes().to_vec()))
733    }
734}
735
736#[cfg(feature = "uuid")]
737impl<'a> From<&'a Uuid> for SQLiteValue<'a> {
738    fn from(value: &'a Uuid) -> Self {
739        SQLiteValue::Blob(Cow::Borrowed(value.as_bytes()))
740    }
741}
742
743// --- Option Types ---
744/// `None` is NULL.
745///
746/// # Panics
747///
748/// Panics when `T`'s conversion fails (for example a JSON payload whose
749/// `Serialize` implementation errors), rather than storing NULL in place of
750/// the value.
751impl<T> From<Option<T>> for SQLiteValue<'_>
752where
753    T: TryInto<Self>,
754{
755    fn from(value: Option<T>) -> Self {
756        value.map_or(SQLiteValue::Null, |v| {
757            v.try_into().unwrap_or_else(|_| {
758                panic!(
759                    "could not convert a `{}` to a SQLite value",
760                    core::any::type_name::<T>()
761                )
762            })
763        })
764    }
765}
766
767// --- Cow integration for SQL struct ---
768impl<'a> From<SQLiteValue<'a>> for Cow<'a, SQLiteValue<'a>> {
769    fn from(value: SQLiteValue<'a>) -> Self {
770        Cow::Owned(value)
771    }
772}
773
774impl<'a> From<&'a SQLiteValue<'a>> for Cow<'a, SQLiteValue<'a>> {
775    fn from(value: &'a SQLiteValue<'a>) -> Self {
776        Cow::Borrowed(value)
777    }
778}
779
780//------------------------------------------------------------------------------
781// TryFrom<SQLiteValue> implementations
782// Uses the FromSQLiteValue trait via convert() for unified conversion logic
783//------------------------------------------------------------------------------
784
785/// Macro to implement `TryFrom`<SQLiteValue> for types implementing `FromSQLiteValue`
786macro_rules! impl_try_from_sqlite_value {
787    ($($ty:ty),* $(,)?) => {
788        $(
789            impl<'a> TryFrom<SQLiteValue<'a>> for $ty {
790                type Error = DrizzleError;
791
792                #[inline]
793                fn try_from(value: SQLiteValue<'a>) -> Result<Self, Self::Error> {
794                    value.convert()
795                }
796            }
797        )*
798    };
799}
800
801impl_try_from_sqlite_value!(
802    i8,
803    i16,
804    i32,
805    i64,
806    isize,
807    u8,
808    u16,
809    u32,
810    u64,
811    usize,
812    f32,
813    f64,
814    bool,
815    String,
816    Box<String>,
817    Rc<String>,
818    Arc<String>,
819    Box<str>,
820    Rc<str>,
821    Arc<str>,
822    Box<Vec<u8>>,
823    Rc<Vec<u8>>,
824    Arc<Vec<u8>>,
825    Vec<u8>,
826    compact_str::CompactString,
827);
828
829#[cfg(feature = "uuid")]
830impl_try_from_sqlite_value!(Uuid);
831
832#[cfg(feature = "chrono")]
833impl_try_from_sqlite_value!(
834    chrono::NaiveDate,
835    chrono::NaiveTime,
836    chrono::NaiveDateTime,
837    chrono::DateTime<chrono::FixedOffset>,
838    chrono::DateTime<chrono::Utc>,
839    chrono::Duration,
840);
841
842#[cfg(feature = "time")]
843impl_try_from_sqlite_value!(
844    time::Date,
845    time::Time,
846    time::PrimitiveDateTime,
847    time::OffsetDateTime,
848    time::Duration,
849);
850
851#[cfg(feature = "rust-decimal")]
852impl_try_from_sqlite_value!(rust_decimal::Decimal);
853
854#[cfg(feature = "serde")]
855impl_try_from_sqlite_value!(serde_json::Value);
856
857#[cfg(feature = "bytes")]
858impl_try_from_sqlite_value!(bytes::Bytes, bytes::BytesMut);
859
860#[cfg(feature = "smallvec")]
861impl<const N: usize> TryFrom<SQLiteValue<'_>> for smallvec::SmallVec<[u8; N]> {
862    type Error = DrizzleError;
863
864    fn try_from(value: SQLiteValue<'_>) -> Result<Self, Self::Error> {
865        value.convert()
866    }
867}
868
869//------------------------------------------------------------------------------
870// TryFrom<&SQLiteValue> implementations for borrowing without consuming
871// Uses the FromSQLiteValue trait via convert_ref() for unified conversion logic
872//------------------------------------------------------------------------------
873
874/// Macro to implement `TryFrom`<&`SQLiteValue`> for types implementing `FromSQLiteValue`
875macro_rules! impl_try_from_sqlite_value_ref {
876    ($($ty:ty),* $(,)?) => {
877        $(
878            impl<'a> TryFrom<&SQLiteValue<'a>> for $ty {
879                type Error = DrizzleError;
880
881                #[inline]
882                fn try_from(value: &SQLiteValue<'a>) -> Result<Self, Self::Error> {
883                    value.convert_ref()
884                }
885            }
886        )*
887    };
888}
889
890impl_try_from_sqlite_value_ref!(
891    i8,
892    i16,
893    i32,
894    i64,
895    isize,
896    u8,
897    u16,
898    u32,
899    u64,
900    usize,
901    f32,
902    f64,
903    bool,
904    String,
905    Box<String>,
906    Rc<String>,
907    Arc<String>,
908    Box<str>,
909    Rc<str>,
910    Arc<str>,
911    Box<Vec<u8>>,
912    Rc<Vec<u8>>,
913    Arc<Vec<u8>>,
914    Vec<u8>,
915    compact_str::CompactString,
916);
917
918#[cfg(feature = "uuid")]
919impl_try_from_sqlite_value_ref!(Uuid);
920
921#[cfg(feature = "chrono")]
922impl_try_from_sqlite_value_ref!(
923    chrono::NaiveDate,
924    chrono::NaiveTime,
925    chrono::NaiveDateTime,
926    chrono::DateTime<chrono::FixedOffset>,
927    chrono::DateTime<chrono::Utc>,
928    chrono::Duration,
929);
930
931#[cfg(feature = "time")]
932impl_try_from_sqlite_value_ref!(
933    time::Date,
934    time::Time,
935    time::PrimitiveDateTime,
936    time::OffsetDateTime,
937    time::Duration,
938);
939
940#[cfg(feature = "rust-decimal")]
941impl_try_from_sqlite_value_ref!(rust_decimal::Decimal);
942
943#[cfg(feature = "serde")]
944impl_try_from_sqlite_value_ref!(serde_json::Value);
945
946#[cfg(feature = "bytes")]
947impl_try_from_sqlite_value_ref!(bytes::Bytes, bytes::BytesMut);
948
949#[cfg(feature = "smallvec")]
950impl<const N: usize> TryFrom<&SQLiteValue<'_>> for smallvec::SmallVec<[u8; N]> {
951    type Error = DrizzleError;
952
953    fn try_from(value: &SQLiteValue<'_>) -> Result<Self, Self::Error> {
954        value.convert_ref()
955    }
956}
957
958// --- Borrowed reference types (cannot use FromSQLiteValue) ---
959
960impl<'a> TryFrom<&'a SQLiteValue<'a>> for &'a str {
961    type Error = DrizzleError;
962
963    fn try_from(value: &'a SQLiteValue<'a>) -> Result<Self, Self::Error> {
964        match value {
965            SQLiteValue::Text(cow) => Ok(cow.as_ref()),
966            _ => Err(DrizzleError::ConversionError(
967                format!("Cannot convert {value:?} to &str").into(),
968            )),
969        }
970    }
971}
972
973impl<'a> TryFrom<&'a SQLiteValue<'a>> for &'a [u8] {
974    type Error = DrizzleError;
975
976    fn try_from(value: &'a SQLiteValue<'a>) -> Result<Self, Self::Error> {
977        match value {
978            SQLiteValue::Blob(cow) => Ok(cow.as_ref()),
979            _ => Err(DrizzleError::ConversionError(
980                format!("Cannot convert {value:?} to &[u8]").into(),
981            )),
982        }
983    }
984}