Skip to main content

drizzle_sqlite/values/owned/
conversions.rs

1//! From<T> and TryFrom<OwnedSQLiteValue> implementations
2
3use super::OwnedSQLiteValue;
4use drizzle_core::error::DrizzleError;
5use std::{borrow::Cow, rc::Rc, sync::Arc};
6
7#[cfg(feature = "uuid")]
8use uuid::Uuid;
9
10//------------------------------------------------------------------------------
11// From<T> implementations
12// Macro-based to reduce boilerplate
13//------------------------------------------------------------------------------
14
15/// Macro to implement From<integer> for OwnedSQLiteValue (converts to INTEGER)
16macro_rules! impl_from_int_for_owned_sqlite_value {
17    ($($ty:ty),* $(,)?) => {
18        $(
19            impl From<$ty> for OwnedSQLiteValue {
20                #[inline]
21                fn from(value: $ty) -> Self {
22                    OwnedSQLiteValue::Integer(value as i64)
23                }
24            }
25
26            impl From<&$ty> for OwnedSQLiteValue {
27                #[inline]
28                fn from(value: &$ty) -> Self {
29                    OwnedSQLiteValue::Integer(*value as i64)
30                }
31            }
32        )*
33    };
34}
35
36/// Macro to implement From<float> for OwnedSQLiteValue (converts to REAL)
37macro_rules! impl_from_float_for_owned_sqlite_value {
38    ($($ty:ty),* $(,)?) => {
39        $(
40            impl From<$ty> for OwnedSQLiteValue {
41                #[inline]
42                fn from(value: $ty) -> Self {
43                    OwnedSQLiteValue::Real(value as f64)
44                }
45            }
46
47            impl From<&$ty> for OwnedSQLiteValue {
48                #[inline]
49                fn from(value: &$ty) -> Self {
50                    OwnedSQLiteValue::Real(*value as f64)
51                }
52            }
53        )*
54    };
55}
56
57// Integer types -> OwnedSQLiteValue::Integer
58impl_from_int_for_owned_sqlite_value!(i8, i16, i32, i64, isize, u8, u16, u32, u64, usize, bool);
59
60// Float types -> OwnedSQLiteValue::Real
61impl_from_float_for_owned_sqlite_value!(f32, f64);
62
63// --- String Types ---
64
65impl From<&str> for OwnedSQLiteValue {
66    fn from(value: &str) -> Self {
67        OwnedSQLiteValue::Text(value.to_string())
68    }
69}
70
71impl From<Cow<'_, str>> for OwnedSQLiteValue {
72    fn from(value: Cow<'_, str>) -> Self {
73        OwnedSQLiteValue::Text(value.into_owned())
74    }
75}
76
77impl From<String> for OwnedSQLiteValue {
78    fn from(value: String) -> Self {
79        OwnedSQLiteValue::Text(value)
80    }
81}
82
83impl From<&String> for OwnedSQLiteValue {
84    fn from(value: &String) -> Self {
85        OwnedSQLiteValue::Text(value.clone())
86    }
87}
88
89impl From<Box<String>> for OwnedSQLiteValue {
90    fn from(value: Box<String>) -> Self {
91        OwnedSQLiteValue::Text(*value)
92    }
93}
94
95impl From<&Box<String>> for OwnedSQLiteValue {
96    fn from(value: &Box<String>) -> Self {
97        OwnedSQLiteValue::Text(value.as_ref().clone())
98    }
99}
100
101impl From<Rc<String>> for OwnedSQLiteValue {
102    fn from(value: Rc<String>) -> Self {
103        OwnedSQLiteValue::Text(value.as_ref().clone())
104    }
105}
106
107impl From<&Rc<String>> for OwnedSQLiteValue {
108    fn from(value: &Rc<String>) -> Self {
109        OwnedSQLiteValue::Text(value.as_ref().clone())
110    }
111}
112
113impl From<Arc<String>> for OwnedSQLiteValue {
114    fn from(value: Arc<String>) -> Self {
115        OwnedSQLiteValue::Text(value.as_ref().clone())
116    }
117}
118
119impl From<&Arc<String>> for OwnedSQLiteValue {
120    fn from(value: &Arc<String>) -> Self {
121        OwnedSQLiteValue::Text(value.as_ref().clone())
122    }
123}
124
125impl From<Box<str>> for OwnedSQLiteValue {
126    fn from(value: Box<str>) -> Self {
127        OwnedSQLiteValue::Text(value.into())
128    }
129}
130
131impl From<&Box<str>> for OwnedSQLiteValue {
132    fn from(value: &Box<str>) -> Self {
133        OwnedSQLiteValue::Text(value.as_ref().to_string())
134    }
135}
136
137impl From<Rc<str>> for OwnedSQLiteValue {
138    fn from(value: Rc<str>) -> Self {
139        OwnedSQLiteValue::Text(value.as_ref().to_string())
140    }
141}
142
143impl From<&Rc<str>> for OwnedSQLiteValue {
144    fn from(value: &Rc<str>) -> Self {
145        OwnedSQLiteValue::Text(value.as_ref().to_string())
146    }
147}
148
149impl From<Arc<str>> for OwnedSQLiteValue {
150    fn from(value: Arc<str>) -> Self {
151        OwnedSQLiteValue::Text(value.as_ref().to_string())
152    }
153}
154
155impl From<&Arc<str>> for OwnedSQLiteValue {
156    fn from(value: &Arc<str>) -> Self {
157        OwnedSQLiteValue::Text(value.as_ref().to_string())
158    }
159}
160
161// --- Binary Data ---
162
163impl From<&[u8]> for OwnedSQLiteValue {
164    fn from(value: &[u8]) -> Self {
165        OwnedSQLiteValue::Blob(value.to_vec().into_boxed_slice())
166    }
167}
168
169impl From<Cow<'_, [u8]>> for OwnedSQLiteValue {
170    fn from(value: Cow<'_, [u8]>) -> Self {
171        OwnedSQLiteValue::Blob(value.into_owned().into_boxed_slice())
172    }
173}
174
175impl From<Vec<u8>> for OwnedSQLiteValue {
176    fn from(value: Vec<u8>) -> Self {
177        OwnedSQLiteValue::Blob(value.into_boxed_slice())
178    }
179}
180
181impl From<Box<Vec<u8>>> for OwnedSQLiteValue {
182    fn from(value: Box<Vec<u8>>) -> Self {
183        OwnedSQLiteValue::Blob(value.into_boxed_slice())
184    }
185}
186
187impl From<&Box<Vec<u8>>> for OwnedSQLiteValue {
188    fn from(value: &Box<Vec<u8>>) -> Self {
189        OwnedSQLiteValue::Blob(value.as_slice().to_vec().into_boxed_slice())
190    }
191}
192
193impl From<Rc<Vec<u8>>> for OwnedSQLiteValue {
194    fn from(value: Rc<Vec<u8>>) -> Self {
195        OwnedSQLiteValue::Blob(value.as_slice().to_vec().into_boxed_slice())
196    }
197}
198
199impl From<&Rc<Vec<u8>>> for OwnedSQLiteValue {
200    fn from(value: &Rc<Vec<u8>>) -> Self {
201        OwnedSQLiteValue::Blob(value.as_slice().to_vec().into_boxed_slice())
202    }
203}
204
205impl From<Arc<Vec<u8>>> for OwnedSQLiteValue {
206    fn from(value: Arc<Vec<u8>>) -> Self {
207        OwnedSQLiteValue::Blob(value.as_slice().to_vec().into_boxed_slice())
208    }
209}
210
211impl From<&Arc<Vec<u8>>> for OwnedSQLiteValue {
212    fn from(value: &Arc<Vec<u8>>) -> Self {
213        OwnedSQLiteValue::Blob(value.as_slice().to_vec().into_boxed_slice())
214    }
215}
216
217// --- UUID ---
218
219#[cfg(feature = "uuid")]
220impl From<Uuid> for OwnedSQLiteValue {
221    fn from(value: Uuid) -> Self {
222        OwnedSQLiteValue::Blob(value.as_bytes().to_vec().into_boxed_slice())
223    }
224}
225
226#[cfg(feature = "uuid")]
227impl From<&Uuid> for OwnedSQLiteValue {
228    fn from(value: &Uuid) -> Self {
229        OwnedSQLiteValue::Blob(value.as_bytes().to_vec().into_boxed_slice())
230    }
231}
232
233#[cfg(feature = "arrayvec")]
234impl<const N: usize> From<arrayvec::ArrayString<N>> for OwnedSQLiteValue {
235    fn from(value: arrayvec::ArrayString<N>) -> Self {
236        OwnedSQLiteValue::Text(value.to_string())
237    }
238}
239
240#[cfg(feature = "arrayvec")]
241impl<const N: usize> From<arrayvec::ArrayVec<u8, N>> for OwnedSQLiteValue {
242    fn from(value: arrayvec::ArrayVec<u8, N>) -> Self {
243        OwnedSQLiteValue::Blob(value.to_vec().into_boxed_slice())
244    }
245}
246
247// --- Option Types ---
248impl<T> From<Option<T>> for OwnedSQLiteValue
249where
250    T: TryInto<OwnedSQLiteValue>,
251{
252    fn from(value: Option<T>) -> Self {
253        match value {
254            Some(value) => value.try_into().unwrap_or(OwnedSQLiteValue::Null),
255            None => OwnedSQLiteValue::Null,
256        }
257    }
258}
259
260//------------------------------------------------------------------------------
261// TryFrom<OwnedSQLiteValue> implementations
262// Uses the FromSQLiteValue trait via convert() for unified conversion logic
263//------------------------------------------------------------------------------
264
265/// Macro to implement TryFrom<OwnedSQLiteValue> for types implementing FromSQLiteValue
266macro_rules! impl_try_from_owned_sqlite_value {
267    ($($ty:ty),* $(,)?) => {
268        $(
269            impl TryFrom<OwnedSQLiteValue> for $ty {
270                type Error = DrizzleError;
271
272                #[inline]
273                fn try_from(value: OwnedSQLiteValue) -> Result<Self, Self::Error> {
274                    value.convert()
275                }
276            }
277        )*
278    };
279}
280
281impl_try_from_owned_sqlite_value!(
282    i8,
283    i16,
284    i32,
285    i64,
286    isize,
287    u8,
288    u16,
289    u32,
290    u64,
291    usize,
292    f32,
293    f64,
294    bool,
295    String,
296    Box<String>,
297    Rc<String>,
298    Arc<String>,
299    Box<str>,
300    Rc<str>,
301    Arc<str>,
302    Box<Vec<u8>>,
303    Rc<Vec<u8>>,
304    Arc<Vec<u8>>,
305    Vec<u8>,
306);
307
308#[cfg(feature = "uuid")]
309impl_try_from_owned_sqlite_value!(Uuid);
310
311#[cfg(feature = "arrayvec")]
312impl<const N: usize> TryFrom<OwnedSQLiteValue> for arrayvec::ArrayString<N> {
313    type Error = DrizzleError;
314
315    fn try_from(value: OwnedSQLiteValue) -> Result<Self, Self::Error> {
316        match value {
317            OwnedSQLiteValue::Text(s) => arrayvec::ArrayString::from(&s).map_err(|_| {
318                DrizzleError::ConversionError(
319                    format!("Text length {} exceeds ArrayString capacity {}", s.len(), N).into(),
320                )
321            }),
322            _ => Err(DrizzleError::ConversionError(
323                format!("Cannot convert {:?} to ArrayString", value).into(),
324            )),
325        }
326    }
327}
328
329#[cfg(feature = "arrayvec")]
330impl<const N: usize> TryFrom<OwnedSQLiteValue> for arrayvec::ArrayVec<u8, N> {
331    type Error = DrizzleError;
332
333    fn try_from(value: OwnedSQLiteValue) -> Result<Self, Self::Error> {
334        match value {
335            OwnedSQLiteValue::Blob(bytes) => {
336                arrayvec::ArrayVec::try_from(bytes.as_ref()).map_err(|_| {
337                    DrizzleError::ConversionError(
338                        format!(
339                            "Blob length {} exceeds ArrayVec capacity {}",
340                            bytes.len(),
341                            N
342                        )
343                        .into(),
344                    )
345                })
346            }
347            _ => Err(DrizzleError::ConversionError(
348                format!("Cannot convert {:?} to ArrayVec<u8>", value).into(),
349            )),
350        }
351    }
352}
353
354//------------------------------------------------------------------------------
355// TryFrom<&OwnedSQLiteValue> implementations for borrowing without consuming
356// Uses the FromSQLiteValue trait via convert_ref() for unified conversion logic
357//------------------------------------------------------------------------------
358
359/// Macro to implement TryFrom<&OwnedSQLiteValue> for types implementing FromSQLiteValue
360macro_rules! impl_try_from_owned_sqlite_value_ref {
361    ($($ty:ty),* $(,)?) => {
362        $(
363            impl TryFrom<&OwnedSQLiteValue> for $ty {
364                type Error = DrizzleError;
365
366                #[inline]
367                fn try_from(value: &OwnedSQLiteValue) -> Result<Self, Self::Error> {
368                    value.convert_ref()
369                }
370            }
371        )*
372    };
373}
374
375impl_try_from_owned_sqlite_value_ref!(
376    i8,
377    i16,
378    i32,
379    i64,
380    isize,
381    u8,
382    u16,
383    u32,
384    u64,
385    usize,
386    f32,
387    f64,
388    bool,
389    String,
390    Box<String>,
391    Rc<String>,
392    Arc<String>,
393    Box<str>,
394    Rc<str>,
395    Arc<str>,
396    Box<Vec<u8>>,
397    Rc<Vec<u8>>,
398    Arc<Vec<u8>>,
399    Vec<u8>,
400);
401
402#[cfg(feature = "uuid")]
403impl_try_from_owned_sqlite_value_ref!(Uuid);
404
405#[cfg(feature = "arrayvec")]
406impl<const N: usize> TryFrom<&OwnedSQLiteValue> for arrayvec::ArrayString<N> {
407    type Error = DrizzleError;
408
409    fn try_from(value: &OwnedSQLiteValue) -> Result<Self, Self::Error> {
410        match value {
411            OwnedSQLiteValue::Text(s) => arrayvec::ArrayString::from(s.as_str()).map_err(|_| {
412                DrizzleError::ConversionError(
413                    format!("Text length {} exceeds ArrayString capacity {}", s.len(), N).into(),
414                )
415            }),
416            _ => Err(DrizzleError::ConversionError(
417                format!("Cannot convert {:?} to ArrayString", value).into(),
418            )),
419        }
420    }
421}
422
423#[cfg(feature = "arrayvec")]
424impl<const N: usize> TryFrom<&OwnedSQLiteValue> for arrayvec::ArrayVec<u8, N> {
425    type Error = DrizzleError;
426
427    fn try_from(value: &OwnedSQLiteValue) -> Result<Self, Self::Error> {
428        match value {
429            OwnedSQLiteValue::Blob(bytes) => {
430                arrayvec::ArrayVec::try_from(bytes.as_ref()).map_err(|_| {
431                    DrizzleError::ConversionError(
432                        format!(
433                            "Blob length {} exceeds ArrayVec capacity {}",
434                            bytes.len(),
435                            N
436                        )
437                        .into(),
438                    )
439                })
440            }
441            _ => Err(DrizzleError::ConversionError(
442                format!("Cannot convert {:?} to ArrayVec<u8>", value).into(),
443            )),
444        }
445    }
446}
447
448// --- Borrowed reference types (cannot use FromSQLiteValue) ---
449
450impl<'a> TryFrom<&'a OwnedSQLiteValue> for &'a str {
451    type Error = DrizzleError;
452
453    fn try_from(value: &'a OwnedSQLiteValue) -> Result<Self, Self::Error> {
454        match value {
455            OwnedSQLiteValue::Text(s) => Ok(s.as_str()),
456            _ => Err(DrizzleError::ConversionError(
457                format!("Cannot convert {:?} to &str", value).into(),
458            )),
459        }
460    }
461}
462
463impl<'a> TryFrom<&'a OwnedSQLiteValue> for &'a [u8] {
464    type Error = DrizzleError;
465
466    fn try_from(value: &'a OwnedSQLiteValue) -> Result<Self, Self::Error> {
467        match value {
468            OwnedSQLiteValue::Blob(b) => Ok(b.as_ref()),
469            _ => Err(DrizzleError::ConversionError(
470                format!("Cannot convert {:?} to &[u8]", value).into(),
471            )),
472        }
473    }
474}