drizzle_sqlite/values/
mod.rs

1//! SQLite value types and conversions
2//!
3//! This module contains the core `SQLiteValue` type and all its conversions.
4
5mod conversions;
6mod drivers;
7mod insert;
8pub mod owned;
9
10pub use insert::*;
11pub use owned::*;
12
13use crate::traits::FromSQLiteValue;
14use drizzle_core::{dialect::Dialect, error::DrizzleError, sql::SQL, traits::SQLParam};
15use std::borrow::Cow;
16
17//------------------------------------------------------------------------------
18// SQLiteValue Definition
19//------------------------------------------------------------------------------
20
21/// Represents a SQLite value
22#[derive(Debug, Clone, PartialEq, PartialOrd, Default)]
23pub enum SQLiteValue<'a> {
24    /// Integer value (i64)
25    Integer(i64),
26    /// Real value (f64)
27    Real(f64),
28    /// Text value (borrowed or owned string)
29    Text(Cow<'a, str>),
30    /// Blob value (borrowed or owned binary data)
31    Blob(Cow<'a, [u8]>),
32    /// NULL value
33    #[default]
34    Null,
35}
36
37impl<'a> SQLiteValue<'a> {
38    /// Returns true if this value is NULL.
39    #[inline]
40    pub const fn is_null(&self) -> bool {
41        matches!(self, SQLiteValue::Null)
42    }
43
44    /// Returns the integer value if this is an INTEGER.
45    #[inline]
46    pub const fn as_i64(&self) -> Option<i64> {
47        match self {
48            SQLiteValue::Integer(value) => Some(*value),
49            _ => None,
50        }
51    }
52
53    /// Returns the real value if this is a REAL.
54    #[inline]
55    pub const fn as_f64(&self) -> Option<f64> {
56        match self {
57            SQLiteValue::Real(value) => Some(*value),
58            _ => None,
59        }
60    }
61
62    /// Returns the text value if this is TEXT.
63    #[inline]
64    pub fn as_str(&self) -> Option<&str> {
65        match self {
66            SQLiteValue::Text(value) => Some(value.as_ref()),
67            _ => None,
68        }
69    }
70
71    /// Returns the blob value if this is BLOB.
72    #[inline]
73    pub fn as_bytes(&self) -> Option<&[u8]> {
74        match self {
75            SQLiteValue::Blob(value) => Some(value.as_ref()),
76            _ => None,
77        }
78    }
79
80    /// Converts this value into an owned representation.
81    #[inline]
82    pub fn into_owned(self) -> OwnedSQLiteValue {
83        self.into()
84    }
85
86    /// Convert this SQLite value to a Rust type using the `FromSQLiteValue` trait.
87    ///
88    /// This provides a unified conversion interface for all types that implement
89    /// `FromSQLiteValue`, including primitives and enum types.
90    ///
91    /// # Example
92    /// ```ignore
93    /// let value = SQLiteValue::Integer(42);
94    /// let num: i64 = value.convert()?;
95    /// ```
96    pub fn convert<T: FromSQLiteValue>(self) -> Result<T, DrizzleError> {
97        match self {
98            SQLiteValue::Integer(i) => T::from_sqlite_integer(i),
99            SQLiteValue::Text(s) => T::from_sqlite_text(&s),
100            SQLiteValue::Real(r) => T::from_sqlite_real(r),
101            SQLiteValue::Blob(b) => T::from_sqlite_blob(&b),
102            SQLiteValue::Null => T::from_sqlite_null(),
103        }
104    }
105
106    /// Convert a reference to this SQLite value to a Rust type.
107    pub fn convert_ref<T: FromSQLiteValue>(&self) -> Result<T, DrizzleError> {
108        match self {
109            SQLiteValue::Integer(i) => T::from_sqlite_integer(*i),
110            SQLiteValue::Text(s) => T::from_sqlite_text(s),
111            SQLiteValue::Real(r) => T::from_sqlite_real(*r),
112            SQLiteValue::Blob(b) => T::from_sqlite_blob(b),
113            SQLiteValue::Null => T::from_sqlite_null(),
114        }
115    }
116}
117
118impl<'a> std::fmt::Display for SQLiteValue<'a> {
119    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
120        let value = match self {
121            SQLiteValue::Integer(i) => i.to_string(),
122            SQLiteValue::Real(r) => r.to_string(),
123            SQLiteValue::Text(cow) => cow.to_string(),
124            SQLiteValue::Blob(cow) => String::from_utf8_lossy(cow).to_string(),
125            SQLiteValue::Null => String::new(),
126        };
127        write!(f, "{value}")
128    }
129}
130
131// Implement core traits required by Drizzle
132impl<'a> SQLParam for SQLiteValue<'a> {
133    const DIALECT: Dialect = Dialect::SQLite;
134}
135
136impl<'a> From<SQLiteValue<'a>> for SQL<'a, SQLiteValue<'a>> {
137    fn from(value: SQLiteValue<'a>) -> Self {
138        SQL::param(value)
139    }
140}
141
142impl<'a> FromIterator<OwnedSQLiteValue> for Vec<SQLiteValue<'a>> {
143    fn from_iter<T: IntoIterator<Item = OwnedSQLiteValue>>(iter: T) -> Self {
144        iter.into_iter().map(SQLiteValue::from).collect()
145    }
146}
147
148impl<'a> FromIterator<&'a OwnedSQLiteValue> for Vec<SQLiteValue<'a>> {
149    fn from_iter<T: IntoIterator<Item = &'a OwnedSQLiteValue>>(iter: T) -> Self {
150        iter.into_iter().map(SQLiteValue::from).collect()
151    }
152}