1use crate::SQLiteValue;
4use crate::traits::FromSQLiteValue;
5use drizzle_core::{SQL, SQLParam, error::DrizzleError};
6
7#[cfg(feature = "rusqlite")]
8use rusqlite::types::FromSql;
9#[cfg(feature = "turso")]
10use turso::IntoValue;
11#[cfg(feature = "uuid")]
12use uuid::Uuid;
13
14use std::borrow::Cow;
15
16#[derive(Debug, Clone, PartialEq, PartialOrd, Default)]
18pub enum OwnedSQLiteValue {
19 Integer(i64),
21 Real(f64),
23 Text(String),
25 Blob(Box<[u8]>),
27 #[default]
29 Null,
30}
31
32impl OwnedSQLiteValue {
33 pub fn convert<T: FromSQLiteValue>(self) -> Result<T, DrizzleError> {
38 match self {
39 OwnedSQLiteValue::Integer(i) => T::from_sqlite_integer(i),
40 OwnedSQLiteValue::Text(s) => T::from_sqlite_text(&s),
41 OwnedSQLiteValue::Real(r) => T::from_sqlite_real(r),
42 OwnedSQLiteValue::Blob(b) => T::from_sqlite_blob(&b),
43 OwnedSQLiteValue::Null => T::from_sqlite_null(),
44 }
45 }
46
47 pub fn convert_ref<T: FromSQLiteValue>(&self) -> Result<T, DrizzleError> {
49 match self {
50 OwnedSQLiteValue::Integer(i) => T::from_sqlite_integer(*i),
51 OwnedSQLiteValue::Text(s) => T::from_sqlite_text(s),
52 OwnedSQLiteValue::Real(r) => T::from_sqlite_real(*r),
53 OwnedSQLiteValue::Blob(b) => T::from_sqlite_blob(b),
54 OwnedSQLiteValue::Null => T::from_sqlite_null(),
55 }
56 }
57}
58
59impl<'a> From<SQLiteValue<'a>> for OwnedSQLiteValue {
60 fn from(value: SQLiteValue<'a>) -> Self {
61 match value {
62 SQLiteValue::Integer(i) => Self::Integer(i),
63 SQLiteValue::Real(r) => Self::Real(r),
64 SQLiteValue::Text(cow) => Self::Text(cow.into_owned()),
65 SQLiteValue::Blob(cow) => Self::Blob(cow.into_owned().into_boxed_slice()),
66 SQLiteValue::Null => Self::Null,
67 }
68 }
69}
70impl<'a> From<&SQLiteValue<'a>> for OwnedSQLiteValue {
71 fn from(value: &SQLiteValue<'a>) -> Self {
72 match value {
73 SQLiteValue::Integer(i) => Self::Integer(*i),
74 SQLiteValue::Real(r) => Self::Real(*r),
75 SQLiteValue::Text(cow) => Self::Text(cow.clone().into_owned()),
76 SQLiteValue::Blob(cow) => Self::Blob(cow.clone().into_owned().into_boxed_slice()),
77 SQLiteValue::Null => Self::Null,
78 }
79 }
80}
81
82impl std::fmt::Display for OwnedSQLiteValue {
83 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
84 let value = match self {
85 OwnedSQLiteValue::Integer(i) => i.to_string(),
86 OwnedSQLiteValue::Real(r) => r.to_string(),
87 OwnedSQLiteValue::Text(s) => s.clone(),
88 OwnedSQLiteValue::Blob(b) => String::from_utf8_lossy(b).to_string(),
89 OwnedSQLiteValue::Null => String::new(),
90 };
91 write!(f, "{value}")
92 }
93}
94
95#[cfg(feature = "rusqlite")]
101impl rusqlite::ToSql for OwnedSQLiteValue {
102 fn to_sql(&self) -> ::rusqlite::Result<::rusqlite::types::ToSqlOutput<'_>> {
103 match self {
104 OwnedSQLiteValue::Null => Ok(rusqlite::types::ToSqlOutput::Owned(
105 rusqlite::types::Value::Null,
106 )),
107 OwnedSQLiteValue::Integer(i) => Ok(rusqlite::types::ToSqlOutput::Owned(
108 rusqlite::types::Value::Integer(*i),
109 )),
110 OwnedSQLiteValue::Real(f) => Ok(rusqlite::types::ToSqlOutput::Owned(
111 rusqlite::types::Value::Real(*f),
112 )),
113 OwnedSQLiteValue::Text(s) => Ok(rusqlite::types::ToSqlOutput::Borrowed(
114 rusqlite::types::ValueRef::Text(s.as_bytes()),
115 )),
116 OwnedSQLiteValue::Blob(b) => Ok(rusqlite::types::ToSqlOutput::Borrowed(
117 rusqlite::types::ValueRef::Blob(b.as_ref()),
118 )),
119 }
120 }
121}
122
123#[cfg(feature = "rusqlite")]
124impl FromSql for OwnedSQLiteValue {
125 fn column_result(value: rusqlite::types::ValueRef<'_>) -> rusqlite::types::FromSqlResult<Self> {
126 let result = match value {
127 rusqlite::types::ValueRef::Null => OwnedSQLiteValue::Null,
128 rusqlite::types::ValueRef::Integer(i) => OwnedSQLiteValue::Integer(i),
129 rusqlite::types::ValueRef::Real(r) => OwnedSQLiteValue::Real(r),
130 rusqlite::types::ValueRef::Text(items) => {
131 OwnedSQLiteValue::Text(String::from_utf8_lossy(items).into_owned())
132 }
133 rusqlite::types::ValueRef::Blob(items) => {
134 OwnedSQLiteValue::Blob(items.to_vec().into_boxed_slice())
135 }
136 };
137 Ok(result)
138 }
139}
140
141#[cfg(feature = "rusqlite")]
142impl From<rusqlite::types::Value> for OwnedSQLiteValue {
143 fn from(value: rusqlite::types::Value) -> Self {
144 match value {
145 rusqlite::types::Value::Null => OwnedSQLiteValue::Null,
146 rusqlite::types::Value::Integer(i) => OwnedSQLiteValue::Integer(i),
147 rusqlite::types::Value::Real(r) => OwnedSQLiteValue::Real(r),
148 rusqlite::types::Value::Text(s) => OwnedSQLiteValue::Text(s),
149 rusqlite::types::Value::Blob(b) => OwnedSQLiteValue::Blob(b.into_boxed_slice()),
150 }
151 }
152}
153
154#[cfg(feature = "rusqlite")]
155impl From<rusqlite::types::ValueRef<'_>> for OwnedSQLiteValue {
156 fn from(value: rusqlite::types::ValueRef<'_>) -> Self {
157 match value {
158 rusqlite::types::ValueRef::Null => OwnedSQLiteValue::Null,
159 rusqlite::types::ValueRef::Integer(i) => OwnedSQLiteValue::Integer(i),
160 rusqlite::types::ValueRef::Real(r) => OwnedSQLiteValue::Real(r),
161 rusqlite::types::ValueRef::Text(items) => {
162 OwnedSQLiteValue::Text(String::from_utf8_lossy(items).into_owned())
163 }
164 rusqlite::types::ValueRef::Blob(items) => {
165 OwnedSQLiteValue::Blob(items.to_vec().into_boxed_slice())
166 }
167 }
168 }
169}
170
171#[cfg(feature = "turso")]
172impl IntoValue for OwnedSQLiteValue {
173 fn into_value(self) -> turso::Result<turso::Value> {
174 let result = match self {
175 OwnedSQLiteValue::Integer(i) => turso::Value::Integer(i),
176 OwnedSQLiteValue::Real(r) => turso::Value::Real(r),
177 OwnedSQLiteValue::Text(s) => turso::Value::Text(s),
178 OwnedSQLiteValue::Blob(b) => turso::Value::Blob(b.into_vec()),
179 OwnedSQLiteValue::Null => turso::Value::Null,
180 };
181 Ok(result)
182 }
183}
184
185#[cfg(feature = "turso")]
186impl IntoValue for &OwnedSQLiteValue {
187 fn into_value(self) -> turso::Result<turso::Value> {
188 let result = match self {
189 OwnedSQLiteValue::Integer(i) => turso::Value::Integer(*i),
190 OwnedSQLiteValue::Real(r) => turso::Value::Real(*r),
191 OwnedSQLiteValue::Text(s) => turso::Value::Text(s.clone()),
192 OwnedSQLiteValue::Blob(b) => turso::Value::Blob(b.to_vec()),
193 OwnedSQLiteValue::Null => turso::Value::Null,
194 };
195 Ok(result)
196 }
197}
198
199#[cfg(feature = "turso")]
200impl From<OwnedSQLiteValue> for turso::Value {
201 fn from(value: OwnedSQLiteValue) -> Self {
202 match value {
203 OwnedSQLiteValue::Integer(i) => turso::Value::Integer(i),
204 OwnedSQLiteValue::Real(r) => turso::Value::Real(r),
205 OwnedSQLiteValue::Text(s) => turso::Value::Text(s),
206 OwnedSQLiteValue::Blob(b) => turso::Value::Blob(b.into_vec()),
207 OwnedSQLiteValue::Null => turso::Value::Null,
208 }
209 }
210}
211
212#[cfg(feature = "turso")]
213impl From<&OwnedSQLiteValue> for turso::Value {
214 fn from(value: &OwnedSQLiteValue) -> Self {
215 match value {
216 OwnedSQLiteValue::Integer(i) => turso::Value::Integer(*i),
217 OwnedSQLiteValue::Real(r) => turso::Value::Real(*r),
218 OwnedSQLiteValue::Text(s) => turso::Value::Text(s.clone()),
219 OwnedSQLiteValue::Blob(b) => turso::Value::Blob(b.to_vec()),
220 OwnedSQLiteValue::Null => turso::Value::Null,
221 }
222 }
223}
224
225#[cfg(feature = "libsql")]
226impl From<OwnedSQLiteValue> for libsql::Value {
227 fn from(value: OwnedSQLiteValue) -> Self {
228 match value {
229 OwnedSQLiteValue::Integer(i) => libsql::Value::Integer(i),
230 OwnedSQLiteValue::Real(r) => libsql::Value::Real(r),
231 OwnedSQLiteValue::Text(s) => libsql::Value::Text(s),
232 OwnedSQLiteValue::Blob(b) => libsql::Value::Blob(b.into_vec()),
233 OwnedSQLiteValue::Null => libsql::Value::Null,
234 }
235 }
236}
237
238#[cfg(feature = "libsql")]
239impl From<&OwnedSQLiteValue> for libsql::Value {
240 fn from(value: &OwnedSQLiteValue) -> Self {
241 match value {
242 OwnedSQLiteValue::Integer(i) => libsql::Value::Integer(*i),
243 OwnedSQLiteValue::Real(r) => libsql::Value::Real(*r),
244 OwnedSQLiteValue::Text(s) => libsql::Value::Text(s.clone()),
245 OwnedSQLiteValue::Blob(b) => libsql::Value::Blob(b.to_vec()),
246 OwnedSQLiteValue::Null => libsql::Value::Null,
247 }
248 }
249}
250
251impl SQLParam for OwnedSQLiteValue {}
253
254impl<'a> From<OwnedSQLiteValue> for SQL<'a, OwnedSQLiteValue> {
255 fn from(value: OwnedSQLiteValue) -> Self {
256 SQL::param(value)
257 }
258}
259
260macro_rules! impl_from_int_for_owned_sqlite_value {
267 ($($ty:ty),* $(,)?) => {
268 $(
269 impl From<$ty> for OwnedSQLiteValue {
270 #[inline]
271 fn from(value: $ty) -> Self {
272 OwnedSQLiteValue::Integer(value as i64)
273 }
274 }
275
276 impl From<&$ty> for OwnedSQLiteValue {
277 #[inline]
278 fn from(value: &$ty) -> Self {
279 OwnedSQLiteValue::Integer(*value as i64)
280 }
281 }
282 )*
283 };
284}
285
286macro_rules! impl_from_float_for_owned_sqlite_value {
288 ($($ty:ty),* $(,)?) => {
289 $(
290 impl From<$ty> for OwnedSQLiteValue {
291 #[inline]
292 fn from(value: $ty) -> Self {
293 OwnedSQLiteValue::Real(value as f64)
294 }
295 }
296
297 impl From<&$ty> for OwnedSQLiteValue {
298 #[inline]
299 fn from(value: &$ty) -> Self {
300 OwnedSQLiteValue::Real(*value as f64)
301 }
302 }
303 )*
304 };
305}
306
307impl_from_int_for_owned_sqlite_value!(i8, i16, i32, i64, isize, u8, u16, u32, u64, usize, bool);
309
310impl_from_float_for_owned_sqlite_value!(f32, f64);
312
313impl From<&str> for OwnedSQLiteValue {
316 fn from(value: &str) -> Self {
317 OwnedSQLiteValue::Text(value.to_string())
318 }
319}
320
321impl From<String> for OwnedSQLiteValue {
322 fn from(value: String) -> Self {
323 OwnedSQLiteValue::Text(value)
324 }
325}
326
327impl From<&String> for OwnedSQLiteValue {
328 fn from(value: &String) -> Self {
329 OwnedSQLiteValue::Text(value.clone())
330 }
331}
332
333impl From<&[u8]> for OwnedSQLiteValue {
336 fn from(value: &[u8]) -> Self {
337 OwnedSQLiteValue::Blob(value.to_vec().into_boxed_slice())
338 }
339}
340
341impl From<Vec<u8>> for OwnedSQLiteValue {
342 fn from(value: Vec<u8>) -> Self {
343 OwnedSQLiteValue::Blob(value.into_boxed_slice())
344 }
345}
346
347#[cfg(feature = "uuid")]
350impl From<Uuid> for OwnedSQLiteValue {
351 fn from(value: Uuid) -> Self {
352 OwnedSQLiteValue::Blob(value.as_bytes().to_vec().into_boxed_slice())
353 }
354}
355
356#[cfg(feature = "uuid")]
357impl From<&Uuid> for OwnedSQLiteValue {
358 fn from(value: &Uuid) -> Self {
359 OwnedSQLiteValue::Blob(value.as_bytes().to_vec().into_boxed_slice())
360 }
361}
362
363impl<T> From<Option<T>> for OwnedSQLiteValue
365where
366 T: TryInto<OwnedSQLiteValue>,
367{
368 fn from(value: Option<T>) -> Self {
369 match value {
370 Some(value) => value.try_into().unwrap_or(OwnedSQLiteValue::Null),
371 None => OwnedSQLiteValue::Null,
372 }
373 }
374}
375
376impl From<OwnedSQLiteValue> for Cow<'_, OwnedSQLiteValue> {
378 fn from(value: OwnedSQLiteValue) -> Self {
379 Cow::Owned(value)
380 }
381}
382
383impl<'a> From<&'a OwnedSQLiteValue> for Cow<'a, OwnedSQLiteValue> {
384 fn from(value: &'a OwnedSQLiteValue) -> Self {
385 Cow::Borrowed(value)
386 }
387}
388
389macro_rules! impl_try_from_owned_sqlite_value {
396 ($($ty:ty),* $(,)?) => {
397 $(
398 impl TryFrom<OwnedSQLiteValue> for $ty {
399 type Error = DrizzleError;
400
401 #[inline]
402 fn try_from(value: OwnedSQLiteValue) -> Result<Self, Self::Error> {
403 value.convert()
404 }
405 }
406 )*
407 };
408}
409
410impl_try_from_owned_sqlite_value!(
411 i8,
412 i16,
413 i32,
414 i64,
415 isize,
416 u8,
417 u16,
418 u32,
419 u64,
420 usize,
421 f32,
422 f64,
423 bool,
424 String,
425 Vec<u8>,
426);
427
428#[cfg(feature = "uuid")]
429impl_try_from_owned_sqlite_value!(Uuid);
430
431macro_rules! impl_try_from_owned_sqlite_value_ref {
438 ($($ty:ty),* $(,)?) => {
439 $(
440 impl TryFrom<&OwnedSQLiteValue> for $ty {
441 type Error = DrizzleError;
442
443 #[inline]
444 fn try_from(value: &OwnedSQLiteValue) -> Result<Self, Self::Error> {
445 value.convert_ref()
446 }
447 }
448 )*
449 };
450}
451
452impl_try_from_owned_sqlite_value_ref!(
453 i8,
454 i16,
455 i32,
456 i64,
457 isize,
458 u8,
459 u16,
460 u32,
461 u64,
462 usize,
463 f32,
464 f64,
465 bool,
466 String,
467 Vec<u8>,
468);
469
470#[cfg(feature = "uuid")]
471impl_try_from_owned_sqlite_value_ref!(Uuid);
472
473impl<'a> TryFrom<&'a OwnedSQLiteValue> for &'a str {
476 type Error = DrizzleError;
477
478 fn try_from(value: &'a OwnedSQLiteValue) -> Result<Self, Self::Error> {
479 match value {
480 OwnedSQLiteValue::Text(s) => Ok(s.as_str()),
481 _ => Err(DrizzleError::ConversionError(
482 format!("Cannot convert {:?} to &str", value).into(),
483 )),
484 }
485 }
486}
487
488impl<'a> TryFrom<&'a OwnedSQLiteValue> for &'a [u8] {
489 type Error = DrizzleError;
490
491 fn try_from(value: &'a OwnedSQLiteValue) -> Result<Self, Self::Error> {
492 match value {
493 OwnedSQLiteValue::Blob(b) => Ok(b.as_ref()),
494 _ => Err(DrizzleError::ConversionError(
495 format!("Cannot convert {:?} to &[u8]", value).into(),
496 )),
497 }
498 }
499}