drizzle_sqlite/
values.rs

1//! SQLite value conversion traits and types
2
3use drizzle_core::{Placeholder, SQL, SQLParam, ToSQL, error::DrizzleError};
4
5mod owned;
6pub use owned::OwnedSQLiteValue;
7
8#[cfg(feature = "rusqlite")]
9use rusqlite::types::FromSql;
10#[cfg(feature = "turso")]
11use turso::IntoValue;
12#[cfg(feature = "uuid")]
13use uuid::Uuid;
14
15use std::borrow::Cow;
16use std::marker::PhantomData;
17
18//------------------------------------------------------------------------------
19// InsertValue Definition - SQL-based value for inserts
20//------------------------------------------------------------------------------
21
22/// Wrapper for SQL with type information
23#[derive(Debug, Clone)]
24pub struct ValueWrapper<'a, V: SQLParam, T> {
25    pub value: SQL<'a, V>,
26    pub _phantom: PhantomData<T>,
27}
28
29impl<'a, V: SQLParam, T> ValueWrapper<'a, V, T> {
30    pub const fn new<U>(value: SQL<'a, V>) -> ValueWrapper<'a, V, U> {
31        ValueWrapper {
32            value,
33            _phantom: PhantomData,
34        }
35    }
36}
37
38/// Represents a value for INSERT operations that can be omitted, null, or a SQL expression
39#[derive(Debug, Clone, Default)]
40pub enum InsertValue<'a, V: SQLParam, T> {
41    /// Omit this column from the INSERT (use database default)
42    #[default]
43    Omit,
44    /// Explicitly insert NULL
45    Null,
46    /// Insert a SQL expression (value, placeholder, etc.)
47    Value(ValueWrapper<'a, V, T>),
48}
49
50impl<'a, T> InsertValue<'a, SQLiteValue<'a>, T> {
51    /// Converts this InsertValue to an owned version with 'static lifetime
52    pub fn into_owned(self) -> InsertValue<'static, SQLiteValue<'static>, T> {
53        match self {
54            InsertValue::Omit => InsertValue::Omit,
55            InsertValue::Null => InsertValue::Null,
56            InsertValue::Value(wrapper) => {
57                // Extract the parameter value, convert to owned, then back to static SQLiteValue
58                if let Some(drizzle_core::SQLChunk::Param(param)) = wrapper.value.chunks.first() {
59                    if let Some(ref val) = param.value {
60                        let owned_val = OwnedSQLiteValue::from(val.as_ref().clone());
61                        let static_val: SQLiteValue<'static> = owned_val.into();
62                        let static_sql = drizzle_core::SQL::parameter(static_val);
63                        InsertValue::Value(ValueWrapper::<SQLiteValue<'static>, T>::new(static_sql))
64                    } else {
65                        InsertValue::Value(ValueWrapper::<SQLiteValue<'static>, T>::new(
66                            drizzle_core::SQL::parameter(SQLiteValue::Null),
67                        ))
68                    }
69                } else {
70                    InsertValue::Value(ValueWrapper::<SQLiteValue<'static>, T>::new(
71                        drizzle_core::SQL::parameter(SQLiteValue::Null),
72                    ))
73                }
74            }
75        }
76    }
77}
78
79// Conversion implementations for SQLiteValue-based InsertValue
80
81// Generic conversion from any type T to InsertValue (for same type T)
82impl<'a, T> From<T> for InsertValue<'a, SQLiteValue<'a>, T>
83where
84    T: TryInto<SQLiteValue<'a>>,
85{
86    fn from(value: T) -> Self {
87        let sql = value
88            .try_into()
89            .map(|v: SQLiteValue<'a>| SQL::from(v))
90            .unwrap_or_else(|_| SQL::from(SQLiteValue::Null));
91        InsertValue::Value(ValueWrapper::<SQLiteValue<'a>, T>::new(sql))
92    }
93}
94
95// Specific conversion for &str to String InsertValue
96impl<'a> From<&str> for InsertValue<'a, SQLiteValue<'a>, String> {
97    fn from(value: &str) -> Self {
98        let sqlite_value = SQL::parameter(Cow::Owned(SQLiteValue::from(value.to_string())));
99        InsertValue::Value(ValueWrapper::<SQLiteValue<'a>, String>::new(sqlite_value))
100    }
101}
102
103// Placeholder conversion for OwnedSQLiteValue
104impl<'a, T> From<Placeholder> for InsertValue<'a, SQLiteValue<'a>, T> {
105    fn from(placeholder: Placeholder) -> Self {
106        // For now, placeholders become Null values in owned context
107        InsertValue::Value(ValueWrapper::<SQLiteValue<'a>, T>::new(
108            SQL::from_placeholder(placeholder),
109        ))
110    }
111}
112
113// Option conversion for OwnedSQLiteValue
114impl<'a, T> From<Option<T>> for InsertValue<'a, SQLiteValue<'a>, T>
115where
116    T: ToSQL<'a, SQLiteValue<'a>>,
117{
118    fn from(value: Option<T>) -> Self {
119        match value {
120            Some(v) => {
121                let sql = v.to_sql();
122                InsertValue::Value(ValueWrapper::<SQLiteValue<'a>, T>::new(sql))
123            }
124            None => InsertValue::Omit,
125        }
126    }
127}
128
129// UUID conversion for String InsertValue (for text columns)
130#[cfg(feature = "uuid")]
131impl<'a> From<Uuid> for InsertValue<'a, SQLiteValue<'a>, String> {
132    fn from(value: Uuid) -> Self {
133        let sqlite_value = SQLiteValue::Text(std::borrow::Cow::Owned(value.to_string()));
134        let sql = SQL::parameter(sqlite_value);
135        InsertValue::Value(ValueWrapper::<SQLiteValue<'a>, String>::new(sql))
136    }
137}
138
139#[cfg(feature = "uuid")]
140impl<'a> From<&'a Uuid> for InsertValue<'a, SQLiteValue<'a>, String> {
141    fn from(value: &'a Uuid) -> Self {
142        let sqlite_value = SQLiteValue::Text(std::borrow::Cow::Owned(value.to_string()));
143        let sql = SQL::parameter(sqlite_value);
144        InsertValue::Value(ValueWrapper::<SQLiteValue<'a>, String>::new(sql))
145    }
146}
147
148// Array conversion for Vec<u8> InsertValue - support flexible input types
149impl<'a, const N: usize> From<[u8; N]> for InsertValue<'a, SQLiteValue<'a>, Vec<u8>> {
150    fn from(value: [u8; N]) -> Self {
151        let sqlite_value = SQLiteValue::Blob(std::borrow::Cow::Owned(value.to_vec()));
152        let sql = SQL::parameter(sqlite_value);
153        InsertValue::Value(ValueWrapper::<SQLiteValue<'a>, Vec<u8>>::new(sql))
154    }
155}
156
157// Slice conversion for Vec<u8> InsertValue
158impl<'a> From<&'a [u8]> for InsertValue<'a, SQLiteValue<'a>, Vec<u8>> {
159    fn from(value: &'a [u8]) -> Self {
160        let sqlite_value = SQLiteValue::Blob(std::borrow::Cow::Borrowed(value));
161        let sql = SQL::parameter(sqlite_value);
162        InsertValue::Value(ValueWrapper::<SQLiteValue<'a>, Vec<u8>>::new(sql))
163    }
164}
165
166// Vec<u8> conversion for Vec<u8> InsertValue
167// impl<'a> From<Vec<u8>> for InsertValue<'a, SQLiteValue<'a>, Vec<u8>> {
168//     fn from(value: Vec<u8>) -> Self {
169//         let sqlite_value = SQLiteValue::Blob(std::borrow::Cow::Owned(value));
170//         let sql = SQL::parameter(sqlite_value);
171//         InsertValue::Value(ValueWrapper::<SQLiteValue<'a>, Vec<u8>>::new(sql))
172//     }
173// }
174
175//------------------------------------------------------------------------------
176// SQLiteValue Definition
177//------------------------------------------------------------------------------
178
179/// Represents a SQLite value
180#[derive(Debug, Clone, PartialEq, PartialOrd, Default)]
181pub enum SQLiteValue<'a> {
182    /// Integer value (i64)
183    Integer(i64),
184    /// Real value (f64)
185    Real(f64),
186    /// Text value (borrowed or owned string)
187    Text(Cow<'a, str>),
188    /// Blob value (borrowed or owned binary data)
189    Blob(Cow<'a, [u8]>),
190    /// NULL value
191    #[default]
192    Null,
193}
194impl<'a> From<OwnedSQLiteValue> for SQLiteValue<'a> {
195    fn from(value: OwnedSQLiteValue) -> Self {
196        match value {
197            OwnedSQLiteValue::Integer(f) => SQLiteValue::Integer(f),
198            OwnedSQLiteValue::Real(r) => SQLiteValue::Real(r),
199            OwnedSQLiteValue::Text(v) => SQLiteValue::Text(Cow::Owned(v)),
200            OwnedSQLiteValue::Blob(v) => SQLiteValue::Blob(Cow::Owned(v.into())),
201            OwnedSQLiteValue::Null => SQLiteValue::Null,
202        }
203    }
204}
205
206impl<'a> std::fmt::Display for SQLiteValue<'a> {
207    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
208        let value = match self {
209            SQLiteValue::Integer(i) => i.to_string(),
210            SQLiteValue::Real(r) => r.to_string(),
211            SQLiteValue::Text(cow) => cow.to_string(),
212            SQLiteValue::Blob(cow) => String::from_utf8_lossy(cow).to_string(),
213            SQLiteValue::Null => String::new(),
214        };
215        write!(f, "{value}")
216    }
217}
218
219impl<'a> From<SQL<'a, SQLiteValue<'a>>> for SQLiteValue<'a> {
220    fn from(_value: SQL<'a, SQLiteValue<'a>>) -> Self {
221        unimplemented!()
222    }
223}
224
225//------------------------------------------------------------------------------
226// Database Driver Implementations
227//------------------------------------------------------------------------------
228
229// Implement rusqlite::ToSql for SQLiteValue when the rusqlite feature is enabled
230#[cfg(feature = "rusqlite")]
231impl<'a> rusqlite::ToSql for SQLiteValue<'a> {
232    fn to_sql(&self) -> ::rusqlite::Result<::rusqlite::types::ToSqlOutput<'_>> {
233        match self {
234            SQLiteValue::Null => Ok(rusqlite::types::ToSqlOutput::Owned(
235                rusqlite::types::Value::Null,
236            )),
237            SQLiteValue::Integer(i) => Ok(rusqlite::types::ToSqlOutput::Owned(
238                rusqlite::types::Value::Integer(*i),
239            )),
240            SQLiteValue::Real(f) => Ok(rusqlite::types::ToSqlOutput::Owned(
241                rusqlite::types::Value::Real(*f),
242            )),
243            SQLiteValue::Text(s) => Ok(rusqlite::types::ToSqlOutput::Borrowed(
244                rusqlite::types::ValueRef::Text(s.as_bytes()),
245            )),
246            SQLiteValue::Blob(b) => Ok(rusqlite::types::ToSqlOutput::Borrowed(
247                rusqlite::types::ValueRef::Blob(b.as_ref()),
248            )),
249        }
250    }
251}
252
253#[cfg(feature = "rusqlite")]
254impl<'a> FromSql for SQLiteValue<'a> {
255    fn column_result(value: rusqlite::types::ValueRef<'_>) -> rusqlite::types::FromSqlResult<Self> {
256        let result = match value {
257            rusqlite::types::ValueRef::Null => SQLiteValue::Null,
258            rusqlite::types::ValueRef::Integer(i) => SQLiteValue::Integer(i),
259            rusqlite::types::ValueRef::Real(r) => SQLiteValue::Real(r),
260            rusqlite::types::ValueRef::Text(items) => {
261                SQLiteValue::Text(String::from_utf8_lossy(items).into_owned().into())
262            }
263            rusqlite::types::ValueRef::Blob(items) => SQLiteValue::Blob(items.to_vec().into()),
264        };
265        Ok(result)
266    }
267}
268
269#[cfg(feature = "rusqlite")]
270impl<'a> From<rusqlite::types::Value> for SQLiteValue<'a> {
271    fn from(value: rusqlite::types::Value) -> Self {
272        match value {
273            rusqlite::types::Value::Null => SQLiteValue::Null,
274            rusqlite::types::Value::Integer(i) => SQLiteValue::Integer(i),
275            rusqlite::types::Value::Real(r) => SQLiteValue::Real(r),
276            rusqlite::types::Value::Text(s) => SQLiteValue::Text(s.into()),
277            rusqlite::types::Value::Blob(b) => SQLiteValue::Blob(b.into()),
278        }
279    }
280}
281
282#[cfg(feature = "rusqlite")]
283impl<'a> From<rusqlite::types::ValueRef<'a>> for SQLiteValue<'a> {
284    fn from(value: rusqlite::types::ValueRef<'a>) -> Self {
285        match value {
286            rusqlite::types::ValueRef::Null => SQLiteValue::Null,
287            rusqlite::types::ValueRef::Integer(i) => SQLiteValue::Integer(i),
288            rusqlite::types::ValueRef::Real(r) => SQLiteValue::Real(r),
289            rusqlite::types::ValueRef::Text(items) => {
290                SQLiteValue::Text(String::from_utf8_lossy(items).into_owned().into())
291            }
292            rusqlite::types::ValueRef::Blob(items) => SQLiteValue::Blob(items.to_vec().into()),
293        }
294    }
295}
296
297#[cfg(feature = "turso")]
298impl<'a> IntoValue for SQLiteValue<'a> {
299    fn into_value(self) -> turso::Result<turso::Value> {
300        let result = match self {
301            SQLiteValue::Integer(i) => turso::Value::Integer(i),
302            SQLiteValue::Real(r) => turso::Value::Real(r),
303            SQLiteValue::Text(cow) => turso::Value::Text(cow.into()),
304            SQLiteValue::Blob(cow) => turso::Value::Blob(cow.into()),
305            SQLiteValue::Null => turso::Value::Null,
306        };
307        Ok(result)
308    }
309}
310
311#[cfg(feature = "turso")]
312impl<'a> IntoValue for &SQLiteValue<'a> {
313    fn into_value(self) -> turso::Result<turso::Value> {
314        let result = match self {
315            SQLiteValue::Integer(i) => turso::Value::Integer(*i),
316            SQLiteValue::Real(r) => turso::Value::Real(*r),
317            SQLiteValue::Text(cow) => turso::Value::Text(cow.to_string()),
318            SQLiteValue::Blob(cow) => turso::Value::Blob(cow.to_vec()),
319            SQLiteValue::Null => turso::Value::Null,
320        };
321        Ok(result)
322    }
323}
324
325#[cfg(feature = "turso")]
326impl<'a> From<SQLiteValue<'a>> for turso::Value {
327    fn from(value: SQLiteValue<'a>) -> Self {
328        match value {
329            SQLiteValue::Integer(i) => turso::Value::Integer(i),
330            SQLiteValue::Real(r) => turso::Value::Real(r),
331            SQLiteValue::Text(cow) => turso::Value::Text(cow.to_string()),
332            SQLiteValue::Blob(cow) => turso::Value::Blob(cow.to_vec()),
333            SQLiteValue::Null => turso::Value::Null,
334        }
335    }
336}
337
338#[cfg(feature = "turso")]
339impl<'a> From<&SQLiteValue<'a>> for turso::Value {
340    fn from(value: &SQLiteValue<'a>) -> Self {
341        match value {
342            SQLiteValue::Integer(i) => turso::Value::Integer(*i),
343            SQLiteValue::Real(r) => turso::Value::Real(*r),
344            SQLiteValue::Text(cow) => turso::Value::Text(cow.to_string()),
345            SQLiteValue::Blob(cow) => turso::Value::Blob(cow.to_vec()),
346            SQLiteValue::Null => turso::Value::Null,
347        }
348    }
349}
350
351#[cfg(feature = "libsql")]
352impl<'a> From<SQLiteValue<'a>> for libsql::Value {
353    fn from(value: SQLiteValue<'a>) -> Self {
354        match value {
355            SQLiteValue::Integer(i) => libsql::Value::Integer(i),
356            SQLiteValue::Real(r) => libsql::Value::Real(r),
357            SQLiteValue::Text(cow) => libsql::Value::Text(cow.to_string()),
358            SQLiteValue::Blob(cow) => libsql::Value::Blob(cow.to_vec()),
359            SQLiteValue::Null => libsql::Value::Null,
360        }
361    }
362}
363
364#[cfg(feature = "libsql")]
365impl<'a> From<&SQLiteValue<'a>> for libsql::Value {
366    fn from(value: &SQLiteValue<'a>) -> Self {
367        match value {
368            SQLiteValue::Integer(i) => libsql::Value::Integer(*i),
369            SQLiteValue::Real(r) => libsql::Value::Real(*r),
370            SQLiteValue::Text(cow) => libsql::Value::Text(cow.to_string()),
371            SQLiteValue::Blob(cow) => libsql::Value::Blob(cow.to_vec()),
372            SQLiteValue::Null => libsql::Value::Null,
373        }
374    }
375}
376
377// Implement core traits required by Drizzle
378impl<'a> drizzle_core::traits::SQLParam for SQLiteValue<'a> {}
379
380impl<'a> From<SQLiteValue<'a>> for SQL<'a, SQLiteValue<'a>> {
381    fn from(value: SQLiteValue<'a>) -> Self {
382        SQL::parameter(value)
383    }
384}
385
386//------------------------------------------------------------------------------
387// From<T> implementations
388//------------------------------------------------------------------------------
389
390// --- Integer Types ---
391
392// i8
393impl<'a> From<i8> for SQLiteValue<'a> {
394    fn from(value: i8) -> Self {
395        SQLiteValue::Integer(value as i64)
396    }
397}
398
399impl<'a> From<&'a i8> for SQLiteValue<'a> {
400    fn from(value: &'a i8) -> Self {
401        SQLiteValue::Integer(*value as i64)
402    }
403}
404
405// i16
406impl<'a> From<i16> for SQLiteValue<'a> {
407    fn from(value: i16) -> Self {
408        SQLiteValue::Integer(value as i64)
409    }
410}
411
412impl<'a> From<&'a i16> for SQLiteValue<'a> {
413    fn from(value: &'a i16) -> Self {
414        SQLiteValue::Integer(*value as i64)
415    }
416}
417
418// i32
419impl<'a> From<i32> for SQLiteValue<'a> {
420    fn from(value: i32) -> Self {
421        SQLiteValue::Integer(value as i64)
422    }
423}
424
425impl<'a> From<&'a i32> for SQLiteValue<'a> {
426    fn from(value: &'a i32) -> Self {
427        SQLiteValue::Integer(*value as i64)
428    }
429}
430
431impl<'a> TryFrom<SQLiteValue<'a>> for i32 {
432    type Error = DrizzleError;
433
434    fn try_from(value: SQLiteValue<'a>) -> Result<Self, Self::Error> {
435        match value {
436            SQLiteValue::Integer(i) => Ok(i.try_into()?),
437            _ => Err(DrizzleError::ConversionError(format!(
438                "Cannot convert {:?} to i32",
439                value
440            ))),
441        }
442    }
443}
444
445// i64
446impl<'a> From<i64> for SQLiteValue<'a> {
447    fn from(value: i64) -> Self {
448        SQLiteValue::Integer(value)
449    }
450}
451
452impl<'a> From<&'a i64> for SQLiteValue<'a> {
453    fn from(value: &'a i64) -> Self {
454        SQLiteValue::Integer(*value)
455    }
456}
457
458// isize
459impl<'a> From<isize> for SQLiteValue<'a> {
460    fn from(value: isize) -> Self {
461        SQLiteValue::Integer(value as i64)
462    }
463}
464
465impl<'a> From<&'a isize> for SQLiteValue<'a> {
466    fn from(value: &'a isize) -> Self {
467        SQLiteValue::Integer(*value as i64)
468    }
469}
470
471// u8
472impl<'a> From<u8> for SQLiteValue<'a> {
473    fn from(value: u8) -> Self {
474        SQLiteValue::Integer(value as i64)
475    }
476}
477
478impl<'a> From<&'a u8> for SQLiteValue<'a> {
479    fn from(value: &'a u8) -> Self {
480        SQLiteValue::Integer(*value as i64)
481    }
482}
483
484// u16
485impl<'a> From<u16> for SQLiteValue<'a> {
486    fn from(value: u16) -> Self {
487        SQLiteValue::Integer(value as i64)
488    }
489}
490
491impl<'a> From<&'a u16> for SQLiteValue<'a> {
492    fn from(value: &'a u16) -> Self {
493        SQLiteValue::Integer(*value as i64)
494    }
495}
496
497// u32
498impl<'a> From<u32> for SQLiteValue<'a> {
499    fn from(value: u32) -> Self {
500        SQLiteValue::Integer(value as i64)
501    }
502}
503
504impl<'a> From<&'a u32> for SQLiteValue<'a> {
505    fn from(value: &'a u32) -> Self {
506        SQLiteValue::Integer(*value as i64)
507    }
508}
509
510// u64
511impl<'a> From<u64> for SQLiteValue<'a> {
512    fn from(value: u64) -> Self {
513        SQLiteValue::Integer(value as i64)
514    }
515}
516
517impl<'a> From<&'a u64> for SQLiteValue<'a> {
518    fn from(value: &'a u64) -> Self {
519        SQLiteValue::Integer(*value as i64)
520    }
521}
522
523// usize
524impl<'a> From<usize> for SQLiteValue<'a> {
525    fn from(value: usize) -> Self {
526        SQLiteValue::Integer(value as i64)
527    }
528}
529
530impl<'a> From<&'a usize> for SQLiteValue<'a> {
531    fn from(value: &'a usize) -> Self {
532        SQLiteValue::Integer(*value as i64)
533    }
534}
535
536// impl<'a, T> From<T> for SQLiteValue<'a>
537// where
538//     T: SQLEnum<Type = SQLiteEnumRepr>,
539// {
540//     fn from(value: T) -> Self {
541//         todo!()
542//     }
543// }
544
545// --- Floating Point Types ---
546
547// f32
548impl<'a> From<f32> for SQLiteValue<'a> {
549    fn from(value: f32) -> Self {
550        SQLiteValue::Real(value as f64)
551    }
552}
553
554impl<'a> From<&'a f32> for SQLiteValue<'a> {
555    fn from(value: &'a f32) -> Self {
556        SQLiteValue::Real(*value as f64)
557    }
558}
559
560// f64
561impl<'a> From<f64> for SQLiteValue<'a> {
562    fn from(value: f64) -> Self {
563        SQLiteValue::Real(value)
564    }
565}
566
567impl<'a> From<&'a f64> for SQLiteValue<'a> {
568    fn from(value: &'a f64) -> Self {
569        SQLiteValue::Real(*value)
570    }
571}
572
573// --- Boolean ---
574
575impl<'a> From<bool> for SQLiteValue<'a> {
576    fn from(value: bool) -> Self {
577        SQLiteValue::Integer(value as i64)
578    }
579}
580
581impl<'a> From<&'a bool> for SQLiteValue<'a> {
582    fn from(value: &'a bool) -> Self {
583        SQLiteValue::Integer(*value as i64)
584    }
585}
586
587// --- String Types ---
588
589impl<'a> From<&'a str> for SQLiteValue<'a> {
590    fn from(value: &'a str) -> Self {
591        SQLiteValue::Text(Cow::Borrowed(value))
592    }
593}
594
595impl<'a> From<String> for SQLiteValue<'a> {
596    fn from(value: String) -> Self {
597        SQLiteValue::Text(Cow::Owned(value))
598    }
599}
600
601impl<'a> From<&'a String> for SQLiteValue<'a> {
602    fn from(value: &'a String) -> Self {
603        SQLiteValue::Text(Cow::Borrowed(value))
604    }
605}
606
607// --- Binary Data ---
608
609impl<'a> From<&'a [u8]> for SQLiteValue<'a> {
610    fn from(value: &'a [u8]) -> Self {
611        SQLiteValue::Blob(Cow::Borrowed(value))
612    }
613}
614
615impl<'a> From<Vec<u8>> for SQLiteValue<'a> {
616    fn from(value: Vec<u8>) -> Self {
617        SQLiteValue::Blob(Cow::Owned(value))
618    }
619}
620
621// --- UUID ---
622
623#[cfg(feature = "uuid")]
624impl<'a> From<Uuid> for SQLiteValue<'a> {
625    fn from(value: Uuid) -> Self {
626        SQLiteValue::Blob(Cow::Owned(value.as_bytes().to_vec()))
627    }
628}
629
630#[cfg(feature = "uuid")]
631impl<'a> From<&'a Uuid> for SQLiteValue<'a> {
632    fn from(value: &'a Uuid) -> Self {
633        SQLiteValue::Blob(Cow::Borrowed(value.as_bytes()))
634    }
635}
636
637// --- JSON ---
638// Note: JSON types should be handled through serialization in the schema macros
639// These implementations provide fallback support but JSON fields should primarily
640// be serialized to TEXT or BLOB through the field generation logic
641
642// --- Option Types ---
643impl<'a, T> From<Option<T>> for SQLiteValue<'a>
644where
645    T: TryInto<SQLiteValue<'a>>,
646{
647    fn from(value: Option<T>) -> Self {
648        match value {
649            Some(value) => value.try_into().unwrap_or(SQLiteValue::Null),
650            None => SQLiteValue::Null,
651        }
652    }
653}
654
655// --- Cow integration for SQL struct ---
656impl<'a> From<SQLiteValue<'a>> for Cow<'a, SQLiteValue<'a>> {
657    fn from(value: SQLiteValue<'a>) -> Self {
658        Cow::Owned(value)
659    }
660}
661
662impl<'a> From<&'a SQLiteValue<'a>> for Cow<'a, SQLiteValue<'a>> {
663    fn from(value: &'a SQLiteValue<'a>) -> Self {
664        Cow::Borrowed(value)
665    }
666}
667
668//------------------------------------------------------------------------------
669// TryFrom<SQLiteValue> implementations
670//------------------------------------------------------------------------------
671
672// --- Integer Types ---
673
674impl<'a> TryFrom<SQLiteValue<'a>> for i8 {
675    type Error = DrizzleError;
676
677    fn try_from(value: SQLiteValue<'a>) -> Result<Self, Self::Error> {
678        match value {
679            SQLiteValue::Integer(i) => Ok(i.try_into()?),
680            _ => Err(DrizzleError::ConversionError(format!(
681                "Cannot convert {:?} to i8",
682                value
683            ))),
684        }
685    }
686}
687
688impl<'a> TryFrom<SQLiteValue<'a>> for i16 {
689    type Error = DrizzleError;
690
691    fn try_from(value: SQLiteValue<'a>) -> Result<Self, Self::Error> {
692        match value {
693            SQLiteValue::Integer(i) => Ok(i.try_into()?),
694            _ => Err(DrizzleError::ConversionError(format!(
695                "Cannot convert {:?} to i16",
696                value
697            ))),
698        }
699    }
700}
701
702impl<'a> TryFrom<SQLiteValue<'a>> for i64 {
703    type Error = DrizzleError;
704
705    fn try_from(value: SQLiteValue<'a>) -> Result<Self, Self::Error> {
706        match value {
707            SQLiteValue::Integer(i) => Ok(i),
708            _ => Err(DrizzleError::ConversionError(format!(
709                "Cannot convert {:?} to i64",
710                value
711            ))),
712        }
713    }
714}
715
716impl<'a> TryFrom<SQLiteValue<'a>> for isize {
717    type Error = DrizzleError;
718
719    fn try_from(value: SQLiteValue<'a>) -> Result<Self, Self::Error> {
720        match value {
721            SQLiteValue::Integer(i) => Ok(i.try_into()?),
722            _ => Err(DrizzleError::ConversionError(format!(
723                "Cannot convert {:?} to isize",
724                value
725            ))),
726        }
727    }
728}
729
730impl<'a> TryFrom<SQLiteValue<'a>> for u8 {
731    type Error = DrizzleError;
732
733    fn try_from(value: SQLiteValue<'a>) -> Result<Self, Self::Error> {
734        match value {
735            SQLiteValue::Integer(i) => Ok(i.try_into()?),
736            _ => Err(DrizzleError::ConversionError(format!(
737                "Cannot convert {:?} to u8",
738                value
739            ))),
740        }
741    }
742}
743
744impl<'a> TryFrom<SQLiteValue<'a>> for u16 {
745    type Error = DrizzleError;
746
747    fn try_from(value: SQLiteValue<'a>) -> Result<Self, Self::Error> {
748        match value {
749            SQLiteValue::Integer(i) => Ok(i.try_into()?),
750            _ => Err(DrizzleError::ConversionError(format!(
751                "Cannot convert {:?} to u16",
752                value
753            ))),
754        }
755    }
756}
757
758impl<'a> TryFrom<SQLiteValue<'a>> for u32 {
759    type Error = DrizzleError;
760
761    fn try_from(value: SQLiteValue<'a>) -> Result<Self, Self::Error> {
762        match value {
763            SQLiteValue::Integer(i) => Ok(i.try_into()?),
764            _ => Err(DrizzleError::ConversionError(format!(
765                "Cannot convert {:?} to u32",
766                value
767            ))),
768        }
769    }
770}
771
772impl<'a> TryFrom<SQLiteValue<'a>> for u64 {
773    type Error = DrizzleError;
774
775    fn try_from(value: SQLiteValue<'a>) -> Result<Self, Self::Error> {
776        match value {
777            SQLiteValue::Integer(i) => Ok(i.try_into()?),
778            _ => Err(DrizzleError::ConversionError(format!(
779                "Cannot convert {:?} to u64",
780                value
781            ))),
782        }
783    }
784}
785
786impl<'a> TryFrom<SQLiteValue<'a>> for usize {
787    type Error = DrizzleError;
788
789    fn try_from(value: SQLiteValue<'a>) -> Result<Self, Self::Error> {
790        match value {
791            SQLiteValue::Integer(i) => Ok(i.try_into()?),
792            _ => Err(DrizzleError::ConversionError(format!(
793                "Cannot convert {:?} to usize",
794                value
795            ))),
796        }
797    }
798}
799
800// --- Floating Point Types ---
801
802impl<'a> TryFrom<SQLiteValue<'a>> for f32 {
803    type Error = DrizzleError;
804
805    fn try_from(value: SQLiteValue<'a>) -> Result<Self, Self::Error> {
806        match value {
807            SQLiteValue::Real(f) => Ok(f as f32),
808            SQLiteValue::Integer(i) => Ok(i as f32),
809            _ => Err(DrizzleError::ConversionError(format!(
810                "Cannot convert {:?} to f32",
811                value
812            ))),
813        }
814    }
815}
816
817impl<'a> TryFrom<SQLiteValue<'a>> for f64 {
818    type Error = DrizzleError;
819
820    fn try_from(value: SQLiteValue<'a>) -> Result<Self, Self::Error> {
821        match value {
822            SQLiteValue::Real(f) => Ok(f),
823            SQLiteValue::Integer(i) => Ok(i as f64),
824            _ => Err(DrizzleError::ConversionError(format!(
825                "Cannot convert {:?} to f64",
826                value
827            ))),
828        }
829    }
830}
831
832// --- Boolean ---
833
834impl<'a> TryFrom<SQLiteValue<'a>> for bool {
835    type Error = DrizzleError;
836
837    fn try_from(value: SQLiteValue<'a>) -> Result<Self, Self::Error> {
838        match value {
839            SQLiteValue::Integer(0) => Ok(false),
840            SQLiteValue::Integer(_) => Ok(true),
841            _ => Err(DrizzleError::ConversionError(format!(
842                "Cannot convert {:?} to bool",
843                value
844            ))),
845        }
846    }
847}
848
849// --- String Types ---
850
851impl<'a> TryFrom<SQLiteValue<'a>> for String {
852    type Error = DrizzleError;
853
854    fn try_from(value: SQLiteValue<'a>) -> Result<Self, Self::Error> {
855        match value {
856            SQLiteValue::Text(cow) => Ok(cow.into_owned()),
857            _ => Err(DrizzleError::ConversionError(format!(
858                "Cannot convert {:?} to String",
859                value
860            ))),
861        }
862    }
863}
864
865// --- Binary Data ---
866
867impl<'a> TryFrom<SQLiteValue<'a>> for Vec<u8> {
868    type Error = DrizzleError;
869
870    fn try_from(value: SQLiteValue<'a>) -> Result<Self, Self::Error> {
871        match value {
872            SQLiteValue::Blob(cow) => Ok(cow.into_owned()),
873            _ => Err(DrizzleError::ConversionError(format!(
874                "Cannot convert {:?} to Vec<u8>",
875                value
876            ))),
877        }
878    }
879}
880
881// --- UUID ---
882
883#[cfg(feature = "uuid")]
884impl<'a> TryFrom<SQLiteValue<'a>> for Uuid {
885    type Error = DrizzleError;
886
887    fn try_from(value: SQLiteValue<'a>) -> Result<Self, Self::Error> {
888        match value {
889            SQLiteValue::Blob(cow) => {
890                let bytes: [u8; 16] = cow.as_ref().try_into().map_err(|_| {
891                    DrizzleError::ConversionError("UUID blob must be exactly 16 bytes".to_string())
892                })?;
893                Ok(Uuid::from_bytes(bytes))
894            }
895            SQLiteValue::Text(cow) => Ok(Uuid::parse_str(cow.as_ref())?),
896            _ => Err(DrizzleError::ConversionError(format!(
897                "Cannot convert {:?} to UUID",
898                value
899            ))),
900        }
901    }
902}
903
904//------------------------------------------------------------------------------
905// TryFrom<&SQLiteValue> implementations for borrowing without consuming
906//------------------------------------------------------------------------------
907
908// --- Integer Types ---
909
910impl<'a> TryFrom<&SQLiteValue<'a>> for i8 {
911    type Error = DrizzleError;
912
913    fn try_from(value: &SQLiteValue<'a>) -> Result<Self, Self::Error> {
914        match value {
915            SQLiteValue::Integer(i) => Ok((*i).try_into()?),
916            _ => Err(DrizzleError::ConversionError(format!(
917                "Cannot convert {:?} to i8",
918                value
919            ))),
920        }
921    }
922}
923
924impl<'a> TryFrom<&SQLiteValue<'a>> for i16 {
925    type Error = DrizzleError;
926
927    fn try_from(value: &SQLiteValue<'a>) -> Result<Self, Self::Error> {
928        match value {
929            SQLiteValue::Integer(i) => Ok((*i).try_into()?),
930            _ => Err(DrizzleError::ConversionError(format!(
931                "Cannot convert {:?} to i16",
932                value
933            ))),
934        }
935    }
936}
937
938impl<'a> TryFrom<&SQLiteValue<'a>> for i32 {
939    type Error = DrizzleError;
940
941    fn try_from(value: &SQLiteValue<'a>) -> Result<Self, Self::Error> {
942        match value {
943            SQLiteValue::Integer(i) => Ok((*i).try_into()?),
944            _ => Err(DrizzleError::ConversionError(format!(
945                "Cannot convert {:?} to i32",
946                value
947            ))),
948        }
949    }
950}
951
952impl<'a> TryFrom<&SQLiteValue<'a>> for i64 {
953    type Error = DrizzleError;
954
955    fn try_from(value: &SQLiteValue<'a>) -> Result<Self, Self::Error> {
956        match value {
957            SQLiteValue::Integer(i) => Ok(*i),
958            _ => Err(DrizzleError::ConversionError(format!(
959                "Cannot convert {:?} to i64",
960                value
961            ))),
962        }
963    }
964}
965
966impl<'a> TryFrom<&SQLiteValue<'a>> for isize {
967    type Error = DrizzleError;
968
969    fn try_from(value: &SQLiteValue<'a>) -> Result<Self, Self::Error> {
970        match value {
971            SQLiteValue::Integer(i) => Ok((*i).try_into()?),
972            _ => Err(DrizzleError::ConversionError(format!(
973                "Cannot convert {:?} to isize",
974                value
975            ))),
976        }
977    }
978}
979
980impl<'a> TryFrom<&SQLiteValue<'a>> for u8 {
981    type Error = DrizzleError;
982
983    fn try_from(value: &SQLiteValue<'a>) -> Result<Self, Self::Error> {
984        match value {
985            SQLiteValue::Integer(i) => Ok((*i).try_into()?),
986            _ => Err(DrizzleError::ConversionError(format!(
987                "Cannot convert {:?} to u8",
988                value
989            ))),
990        }
991    }
992}
993
994impl<'a> TryFrom<&SQLiteValue<'a>> for u16 {
995    type Error = DrizzleError;
996
997    fn try_from(value: &SQLiteValue<'a>) -> Result<Self, Self::Error> {
998        match value {
999            SQLiteValue::Integer(i) => Ok((*i).try_into()?),
1000            _ => Err(DrizzleError::ConversionError(format!(
1001                "Cannot convert {:?} to u16",
1002                value
1003            ))),
1004        }
1005    }
1006}
1007
1008impl<'a> TryFrom<&SQLiteValue<'a>> for u32 {
1009    type Error = DrizzleError;
1010
1011    fn try_from(value: &SQLiteValue<'a>) -> Result<Self, Self::Error> {
1012        match value {
1013            SQLiteValue::Integer(i) => Ok((*i).try_into()?),
1014            _ => Err(DrizzleError::ConversionError(format!(
1015                "Cannot convert {:?} to u32",
1016                value
1017            ))),
1018        }
1019    }
1020}
1021
1022impl<'a> TryFrom<&SQLiteValue<'a>> for u64 {
1023    type Error = DrizzleError;
1024
1025    fn try_from(value: &SQLiteValue<'a>) -> Result<Self, Self::Error> {
1026        match value {
1027            SQLiteValue::Integer(i) => Ok((*i).try_into()?),
1028            _ => Err(DrizzleError::ConversionError(format!(
1029                "Cannot convert {:?} to u64",
1030                value
1031            ))),
1032        }
1033    }
1034}
1035
1036impl<'a> TryFrom<&SQLiteValue<'a>> for usize {
1037    type Error = DrizzleError;
1038
1039    fn try_from(value: &SQLiteValue<'a>) -> Result<Self, Self::Error> {
1040        match value {
1041            SQLiteValue::Integer(i) => Ok((*i).try_into()?),
1042            _ => Err(DrizzleError::ConversionError(format!(
1043                "Cannot convert {:?} to usize",
1044                value
1045            ))),
1046        }
1047    }
1048}
1049
1050// --- Floating Point Types ---
1051
1052impl<'a> TryFrom<&SQLiteValue<'a>> for f32 {
1053    type Error = DrizzleError;
1054
1055    fn try_from(value: &SQLiteValue<'a>) -> Result<Self, Self::Error> {
1056        match value {
1057            SQLiteValue::Real(f) => Ok(*f as f32),
1058            SQLiteValue::Integer(i) => Ok(*i as f32),
1059            _ => Err(DrizzleError::ConversionError(format!(
1060                "Cannot convert {:?} to f32",
1061                value
1062            ))),
1063        }
1064    }
1065}
1066
1067impl<'a> TryFrom<&SQLiteValue<'a>> for f64 {
1068    type Error = DrizzleError;
1069
1070    fn try_from(value: &SQLiteValue<'a>) -> Result<Self, Self::Error> {
1071        match value {
1072            SQLiteValue::Real(f) => Ok(*f),
1073            SQLiteValue::Integer(i) => Ok(*i as f64),
1074            _ => Err(DrizzleError::ConversionError(format!(
1075                "Cannot convert {:?} to f64",
1076                value
1077            ))),
1078        }
1079    }
1080}
1081
1082// --- Boolean ---
1083
1084impl<'a> TryFrom<&SQLiteValue<'a>> for bool {
1085    type Error = DrizzleError;
1086
1087    fn try_from(value: &SQLiteValue<'a>) -> Result<Self, Self::Error> {
1088        match value {
1089            SQLiteValue::Integer(0) => Ok(false),
1090            SQLiteValue::Integer(_) => Ok(true),
1091            _ => Err(DrizzleError::ConversionError(format!(
1092                "Cannot convert {:?} to bool",
1093                value
1094            ))),
1095        }
1096    }
1097}
1098
1099// --- String Types ---
1100
1101impl<'a> TryFrom<&SQLiteValue<'a>> for String {
1102    type Error = DrizzleError;
1103
1104    fn try_from(value: &SQLiteValue<'a>) -> Result<Self, Self::Error> {
1105        match value {
1106            SQLiteValue::Text(cow) => Ok(cow.to_string()),
1107            _ => Err(DrizzleError::ConversionError(format!(
1108                "Cannot convert {:?} to String",
1109                value
1110            ))),
1111        }
1112    }
1113}
1114
1115impl<'a> TryFrom<&'a SQLiteValue<'a>> for &'a str {
1116    type Error = DrizzleError;
1117
1118    fn try_from(value: &'a SQLiteValue<'a>) -> Result<Self, Self::Error> {
1119        match value {
1120            SQLiteValue::Text(cow) => Ok(cow.as_ref()),
1121            _ => Err(DrizzleError::ConversionError(format!(
1122                "Cannot convert {:?} to &str",
1123                value
1124            ))),
1125        }
1126    }
1127}
1128
1129// --- Binary Data ---
1130
1131impl<'a> TryFrom<&SQLiteValue<'a>> for Vec<u8> {
1132    type Error = DrizzleError;
1133
1134    fn try_from(value: &SQLiteValue<'a>) -> Result<Self, Self::Error> {
1135        match value {
1136            SQLiteValue::Blob(cow) => Ok(cow.to_vec()),
1137            _ => Err(DrizzleError::ConversionError(format!(
1138                "Cannot convert {:?} to Vec<u8>",
1139                value
1140            ))),
1141        }
1142    }
1143}
1144
1145impl<'a> TryFrom<&'a SQLiteValue<'a>> for &'a [u8] {
1146    type Error = DrizzleError;
1147
1148    fn try_from(value: &'a SQLiteValue<'a>) -> Result<Self, Self::Error> {
1149        match value {
1150            SQLiteValue::Blob(cow) => Ok(cow.as_ref()),
1151            _ => Err(DrizzleError::ConversionError(format!(
1152                "Cannot convert {:?} to &[u8]",
1153                value
1154            ))),
1155        }
1156    }
1157}
1158
1159// --- UUID ---
1160
1161#[cfg(feature = "uuid")]
1162impl<'a> TryFrom<&SQLiteValue<'a>> for Uuid {
1163    type Error = DrizzleError;
1164
1165    fn try_from(value: &SQLiteValue<'a>) -> Result<Self, Self::Error> {
1166        match value {
1167            SQLiteValue::Blob(cow) => {
1168                let bytes: [u8; 16] = cow.as_ref().try_into().map_err(|_| {
1169                    DrizzleError::ConversionError("UUID blob must be exactly 16 bytes".to_string())
1170                })?;
1171                Ok(Uuid::from_bytes(bytes))
1172            }
1173            SQLiteValue::Text(cow) => Ok(Uuid::parse_str(cow.as_ref())?),
1174            _ => Err(DrizzleError::ConversionError(format!(
1175                "Cannot convert {:?} to UUID",
1176                value
1177            ))),
1178        }
1179    }
1180}