Skip to main content

drizzle_sqlite/values/owned/
mod.rs

1//! Owned `SQLite` value type and implementations
2
3mod conversions;
4mod drivers;
5
6use super::SQLiteValue;
7use crate::prelude::*;
8use crate::traits::FromSQLiteValue;
9use drizzle_core::{error::DrizzleError, sql::SQL, traits::SQLParam};
10
11/// Represents a `SQLite` value (owned version)
12#[derive(Debug, Clone, PartialEq, PartialOrd, Default)]
13pub enum OwnedSQLiteValue {
14    /// Integer value (i64)
15    Integer(i64),
16    /// Real value (f64)
17    Real(f64),
18    /// Text value (owned string)
19    Text(String),
20    /// Blob value (owned binary data)
21    Blob(Box<[u8]>),
22    /// NULL value
23    #[default]
24    Null,
25}
26
27impl OwnedSQLiteValue {
28    /// Returns true if this value is NULL.
29    #[inline]
30    #[must_use]
31    pub const fn is_null(&self) -> bool {
32        matches!(self, Self::Null)
33    }
34
35    /// Returns the integer value if this is an INTEGER.
36    #[inline]
37    #[must_use]
38    pub const fn as_i64(&self) -> Option<i64> {
39        match self {
40            Self::Integer(value) => Some(*value),
41            _ => None,
42        }
43    }
44
45    /// Returns the real value if this is a REAL.
46    #[inline]
47    #[must_use]
48    pub const fn as_f64(&self) -> Option<f64> {
49        match self {
50            Self::Real(value) => Some(*value),
51            _ => None,
52        }
53    }
54
55    /// Returns the text value if this is TEXT.
56    #[inline]
57    #[must_use]
58    pub const fn as_str(&self) -> Option<&str> {
59        match self {
60            Self::Text(value) => Some(value.as_str()),
61            _ => None,
62        }
63    }
64
65    /// Returns the blob value if this is BLOB.
66    #[inline]
67    #[must_use]
68    pub fn as_bytes(&self) -> Option<&[u8]> {
69        match self {
70            Self::Blob(value) => Some(value.as_ref()),
71            _ => None,
72        }
73    }
74
75    /// Returns a borrowed `SQLiteValue` view of this owned value.
76    #[inline]
77    #[must_use]
78    pub fn as_value(&self) -> SQLiteValue<'_> {
79        match self {
80            Self::Integer(value) => SQLiteValue::Integer(*value),
81            Self::Real(value) => SQLiteValue::Real(*value),
82            Self::Text(value) => SQLiteValue::Text(Cow::Borrowed(value)),
83            Self::Blob(value) => SQLiteValue::Blob(Cow::Borrowed(value)),
84            Self::Null => SQLiteValue::Null,
85        }
86    }
87
88    /// Convert this `SQLite` value to a Rust type using the `FromSQLiteValue` trait.
89    ///
90    /// This provides a unified conversion interface for all types that implement
91    /// `FromSQLiteValue`, including primitives and enum types.
92    ///
93    /// # Errors
94    ///
95    /// Returns [`DrizzleError::ConversionError`] when the stored variant cannot
96    /// be decoded into `T`.
97    pub fn convert<T: FromSQLiteValue>(self) -> Result<T, DrizzleError> {
98        match self {
99            Self::Integer(i) => T::from_sqlite_integer(i),
100            Self::Text(s) => T::from_sqlite_text(&s),
101            Self::Real(r) => T::from_sqlite_real(r),
102            Self::Blob(b) => T::from_sqlite_blob(&b),
103            Self::Null => T::from_sqlite_null(),
104        }
105    }
106
107    /// Convert a reference to this `SQLite` value to a Rust type.
108    ///
109    /// # Errors
110    ///
111    /// Returns [`DrizzleError::ConversionError`] when the stored variant cannot
112    /// be decoded into `T`.
113    pub fn convert_ref<T: FromSQLiteValue>(&self) -> Result<T, DrizzleError> {
114        match self {
115            Self::Integer(i) => T::from_sqlite_integer(*i),
116            Self::Text(s) => T::from_sqlite_text(s),
117            Self::Real(r) => T::from_sqlite_real(*r),
118            Self::Blob(b) => T::from_sqlite_blob(b),
119            Self::Null => T::from_sqlite_null(),
120        }
121    }
122}
123
124impl core::fmt::Display for OwnedSQLiteValue {
125    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
126        let value = match self {
127            Self::Integer(i) => i.to_string(),
128            Self::Real(r) => r.to_string(),
129            Self::Text(s) => s.clone(),
130            Self::Blob(b) => String::from_utf8_lossy(b).to_string(),
131            Self::Null => String::new(),
132        };
133        write!(f, "{value}")
134    }
135}
136
137//------------------------------------------------------------------------------
138// Core From<SQLiteValue> conversions
139//------------------------------------------------------------------------------
140
141impl<'a> From<SQLiteValue<'a>> for OwnedSQLiteValue {
142    fn from(value: SQLiteValue<'a>) -> Self {
143        match value {
144            SQLiteValue::Integer(i) => Self::Integer(i),
145            SQLiteValue::Real(r) => Self::Real(r),
146            SQLiteValue::Text(cow) => Self::Text(cow.into_owned()),
147            SQLiteValue::Blob(cow) => Self::Blob(cow.into_owned().into_boxed_slice()),
148            SQLiteValue::Null => Self::Null,
149        }
150    }
151}
152
153impl<'a> From<&SQLiteValue<'a>> for OwnedSQLiteValue {
154    fn from(value: &SQLiteValue<'a>) -> Self {
155        match value {
156            SQLiteValue::Integer(i) => Self::Integer(*i),
157            SQLiteValue::Real(r) => Self::Real(*r),
158            SQLiteValue::Text(cow) => Self::Text(cow.clone().into_owned()),
159            SQLiteValue::Blob(cow) => Self::Blob(cow.clone().into_owned().into_boxed_slice()),
160            SQLiteValue::Null => Self::Null,
161        }
162    }
163}
164
165//------------------------------------------------------------------------------
166// Core traits required by Drizzle
167//------------------------------------------------------------------------------
168
169impl SQLParam for OwnedSQLiteValue {
170    const DIALECT: drizzle_core::Dialect = drizzle_core::Dialect::SQLite;
171    type DialectMarker = drizzle_core::dialect::SQLiteDialect;
172}
173
174impl From<OwnedSQLiteValue> for SQL<'_, OwnedSQLiteValue> {
175    fn from(value: OwnedSQLiteValue) -> Self {
176        SQL::param(value)
177    }
178}
179
180//------------------------------------------------------------------------------
181// Cow integration for SQL struct
182//------------------------------------------------------------------------------
183
184impl From<OwnedSQLiteValue> for Cow<'_, OwnedSQLiteValue> {
185    fn from(value: OwnedSQLiteValue) -> Self {
186        Cow::Owned(value)
187    }
188}
189
190impl<'a> From<&'a OwnedSQLiteValue> for Cow<'a, OwnedSQLiteValue> {
191    fn from(value: &'a OwnedSQLiteValue) -> Self {
192        Cow::Borrowed(value)
193    }
194}