Skip to main content

sqlite_provider/
value.rs

1use crate::provider::{RawBytes, ValueType};
2
3/// Owned SQLite value.
4#[derive(Clone, Debug, PartialEq)]
5pub enum Value {
6    Null,
7    Integer(i64),
8    Float(f64),
9    Text(String),
10    Blob(Vec<u8>),
11}
12
13impl Value {
14    pub fn value_type(&self) -> ValueType {
15        match self {
16            Value::Null => ValueType::Null,
17            Value::Integer(_) => ValueType::Integer,
18            Value::Float(_) => ValueType::Float,
19            Value::Text(_) => ValueType::Text,
20            Value::Blob(_) => ValueType::Blob,
21        }
22    }
23
24    pub fn as_i64(&self) -> Option<i64> {
25        match self {
26            Value::Integer(v) => Some(*v),
27            _ => None,
28        }
29    }
30
31    pub fn as_f64(&self) -> Option<f64> {
32        match self {
33            Value::Float(v) => Some(*v),
34            _ => None,
35        }
36    }
37
38    pub fn as_str(&self) -> Option<&str> {
39        match self {
40            Value::Text(v) => Some(v.as_str()),
41            _ => None,
42        }
43    }
44
45    pub fn as_blob(&self) -> Option<&[u8]> {
46        match self {
47            Value::Blob(v) => Some(v.as_slice()),
48            _ => None,
49        }
50    }
51}
52
53impl From<i64> for Value {
54    fn from(value: i64) -> Self {
55        Value::Integer(value)
56    }
57}
58
59impl From<f64> for Value {
60    fn from(value: f64) -> Self {
61        Value::Float(value)
62    }
63}
64
65impl From<String> for Value {
66    fn from(value: String) -> Self {
67        Value::Text(value)
68    }
69}
70
71impl From<&str> for Value {
72    fn from(value: &str) -> Self {
73        Value::Text(value.to_owned())
74    }
75}
76
77impl From<Vec<u8>> for Value {
78    fn from(value: Vec<u8>) -> Self {
79        Value::Blob(value)
80    }
81}
82
83/// Borrowed SQLite value view.
84#[derive(Clone, Copy, Debug, PartialEq)]
85pub enum ValueRef<'a> {
86    Null,
87    Integer(i64),
88    Float(f64),
89    Text(&'a str),
90    Blob(&'a [u8]),
91}
92
93impl<'a> ValueRef<'a> {
94    pub fn value_type(&self) -> ValueType {
95        match self {
96            ValueRef::Null => ValueType::Null,
97            ValueRef::Integer(_) => ValueType::Integer,
98            ValueRef::Float(_) => ValueType::Float,
99            ValueRef::Text(_) => ValueType::Text,
100            ValueRef::Blob(_) => ValueType::Blob,
101        }
102    }
103
104    pub fn as_i64(&self) -> Option<i64> {
105        match self {
106            ValueRef::Integer(v) => Some(*v),
107            _ => None,
108        }
109    }
110
111    pub fn as_f64(&self) -> Option<f64> {
112        match self {
113            ValueRef::Float(v) => Some(*v),
114            _ => None,
115        }
116    }
117
118    pub fn as_str(&self) -> Option<&'a str> {
119        match self {
120            ValueRef::Text(v) => Some(*v),
121            _ => None,
122        }
123    }
124
125    pub fn as_blob(&self) -> Option<&'a [u8]> {
126        match self {
127            ValueRef::Blob(v) => Some(*v),
128            _ => None,
129        }
130    }
131
132    pub fn to_owned(&self) -> Value {
133        match self {
134            ValueRef::Null => Value::Null,
135            ValueRef::Integer(v) => Value::Integer(*v),
136            ValueRef::Float(v) => Value::Float(*v),
137            ValueRef::Text(v) => Value::Text((*v).to_owned()),
138            ValueRef::Blob(v) => Value::Blob((*v).to_vec()),
139        }
140    }
141
142    /// # Safety
143    /// Caller must ensure `raw` points to valid UTF-8 for the duration of `'a`.
144    pub unsafe fn from_raw_text(raw: RawBytes) -> ValueRef<'a> {
145        ValueRef::Text(unsafe { raw.as_str_unchecked() })
146    }
147
148    /// # Safety
149    /// Caller must ensure `raw` points to valid bytes for the duration of `'a`.
150    pub unsafe fn from_raw_blob(raw: RawBytes) -> ValueRef<'a> {
151        ValueRef::Blob(unsafe { raw.as_slice() })
152    }
153}
154
155#[cfg(test)]
156mod tests {
157    use super::{Value, ValueRef};
158
159    #[test]
160    fn value_ref_to_owned() {
161        let value = ValueRef::Text("hello");
162        assert_eq!(value.to_owned(), Value::Text("hello".to_owned()));
163    }
164}