Skip to main content

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