drizzle_sqlite/values/
owned.rs

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