sqlite_ll/
value.rs

1use core::ffi::c_int;
2use core::fmt;
3
4use alloc::string::String;
5use alloc::vec::Vec;
6
7use sqlite3_sys as ffi;
8
9/// The type of a value.
10#[derive(Clone, Copy, Debug, Eq, PartialEq)]
11#[non_exhaustive]
12pub struct Type(c_int);
13
14impl Type {
15    /// Construct from a raw type.
16    #[inline]
17    pub(crate) fn from_raw(raw: c_int) -> Self {
18        Self(raw)
19    }
20
21    /// The blob type.
22    pub const BLOB: Self = Self(ffi::SQLITE_BLOB);
23    /// The text type.
24    pub const TEXT: Self = Self(ffi::SQLITE_TEXT);
25    /// The floating-point type.
26    pub const FLOAT: Self = Self(ffi::SQLITE_FLOAT);
27    /// The integer type.
28    pub const INTEGER: Self = Self(ffi::SQLITE_INTEGER);
29    /// The null type.
30    pub const NULL: Self = Self(ffi::SQLITE_NULL);
31}
32
33impl fmt::Display for Type {
34    #[inline]
35    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36        match self.0 {
37            ffi::SQLITE_BLOB => write!(f, "BLOB"),
38            ffi::SQLITE_TEXT => write!(f, "TEXT"),
39            ffi::SQLITE_FLOAT => write!(f, "FLOAT"),
40            ffi::SQLITE_INTEGER => write!(f, "INTEGER"),
41            ffi::SQLITE_NULL => write!(f, "NULL"),
42            _ => write!(f, "UNKNOWN"),
43        }
44    }
45}
46
47#[derive(Clone, Debug, PartialEq)]
48pub(crate) enum Kind {
49    Null,
50    Blob(Vec<u8>),
51    Text(String),
52    Float(f64),
53    Integer(i64),
54}
55
56/// A dynamic value.
57#[derive(Clone, PartialEq)]
58pub struct Value {
59    pub(super) kind: Kind,
60}
61
62impl Value {
63    /// Construct a null value.
64    ///
65    /// # Examples
66    ///
67    /// ```
68    /// use sqlite_ll::Value;
69    ///
70    /// let value = Value::null();
71    /// assert!(value.is_null());
72    /// ```
73    #[inline]
74    pub const fn null() -> Self {
75        Self { kind: Kind::Null }
76    }
77
78    /// Construct a blob value.
79    ///
80    /// # Examples
81    ///
82    /// ```
83    /// use sqlite_ll::Value;
84    ///
85    /// let value = Value::blob(Vec::new());
86    /// assert_eq!(value.as_blob(), Some(&[][..]));
87    /// ```
88    #[inline]
89    pub const fn blob(value: Vec<u8>) -> Self {
90        Self {
91            kind: Kind::Blob(value),
92        }
93    }
94
95    /// Construct a text value.
96    ///
97    /// # Examples
98    ///
99    /// ```
100    /// use sqlite_ll::Value;
101    ///
102    /// let value = Value::text(String::new());
103    /// assert_eq!(value.as_text(), Some(""));
104    ///
105    /// let value = Value::text(String::from("hello"));
106    /// assert_eq!(value.as_text(), Some("hello"));
107    /// ```
108    #[inline]
109    pub const fn text(value: String) -> Self {
110        Self {
111            kind: Kind::Text(value),
112        }
113    }
114
115    /// Construct a float value.
116    ///
117    /// # Examples
118    ///
119    /// ```
120    /// use sqlite_ll::Value;
121    ///
122    /// let value = Value::float(42.0);
123    /// assert_eq!(value.as_float(), Some(42.0));
124    /// ```
125    #[inline]
126    pub const fn float(value: f64) -> Self {
127        Self {
128            kind: Kind::Float(value),
129        }
130    }
131
132    /// Construct a integer value.
133    ///
134    /// # Examples
135    ///
136    /// ```
137    /// use sqlite_ll::Value;
138    ///
139    /// let value = Value::integer(42);
140    /// assert_eq!(value.as_integer(), Some(42));
141    /// ```
142    #[inline]
143    pub const fn integer(value: i64) -> Self {
144        Self {
145            kind: Kind::Integer(value),
146        }
147    }
148
149    /// Return whether the value is `Null`.
150    ///
151    /// # Examples
152    ///
153    /// ```
154    /// use sqlite_ll::Value;
155    ///
156    /// let value = Value::null();
157    /// assert!(value.is_null());
158    /// ```
159    #[inline]
160    pub const fn is_null(&self) -> bool {
161        matches!(self.kind, Kind::Null)
162    }
163
164    /// Return the binary data if the value is `Binary`.
165    ///
166    /// # Examples
167    ///
168    /// ```
169    /// use sqlite_ll::Value;
170    ///
171    /// let value = Value::blob(Vec::new());
172    /// assert_eq!(value.as_blob(), Some(&[][..]));
173    /// ```
174    #[inline]
175    pub const fn as_blob(&self) -> Option<&[u8]> {
176        if let Kind::Blob(value) = &self.kind {
177            return Some(value.as_slice());
178        }
179
180        None
181    }
182
183    /// Return the string if the value is `String`.
184    ///
185    /// # Examples
186    ///
187    /// ```
188    /// use sqlite_ll::Value;
189    ///
190    /// let value = Value::text(String::new());
191    /// assert_eq!(value.as_text(), Some(""));
192    ///
193    /// let value = Value::text(String::from("hello"));
194    /// assert_eq!(value.as_text(), Some("hello"));
195    /// ```
196    #[inline]
197    pub const fn as_text(&self) -> Option<&str> {
198        if let Kind::Text(value) = &self.kind {
199            return Some(value.as_str());
200        }
201
202        None
203    }
204
205    /// Return the floating-point number if the value is `Float`.
206    ///
207    /// # Examples
208    ///
209    /// ```
210    /// use sqlite_ll::Value;
211    ///
212    /// let value = Value::float(42.0);
213    /// assert_eq!(value.as_float(), Some(42.0));
214    /// ```
215    #[inline]
216    pub const fn as_float(&self) -> Option<f64> {
217        if let Kind::Float(value) = self.kind {
218            return Some(value);
219        }
220
221        None
222    }
223
224    /// Return the integer number if the value is `Integer`.
225    ///
226    /// # Examples
227    ///
228    /// ```
229    /// use sqlite_ll::Value;
230    ///
231    /// let value = Value::integer(42);
232    /// assert_eq!(value.as_integer(), Some(42));
233    /// ```
234    #[inline]
235    pub const fn as_integer(&self) -> Option<i64> {
236        if let Kind::Integer(value) = self.kind {
237            return Some(value);
238        }
239
240        None
241    }
242
243    /// Return the type.
244    #[inline]
245    pub const fn kind(&self) -> Type {
246        match &self.kind {
247            Kind::Blob(_) => Type::BLOB,
248            Kind::Float(_) => Type::FLOAT,
249            Kind::Integer(_) => Type::INTEGER,
250            Kind::Text(_) => Type::TEXT,
251            Kind::Null => Type::NULL,
252        }
253    }
254}
255
256impl fmt::Debug for Value {
257    #[inline]
258    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
259        self.kind.fmt(f)
260    }
261}