geekorm_core/builder/values/
mod.rs

1use std::{fmt::Display, str};
2
3use serde::{Deserialize, Serialize, Serializer};
4
5#[cfg(feature = "chrono")]
6pub(crate) mod valchrono;
7#[cfg(feature = "semver")]
8pub(crate) mod valsemver;
9#[cfg(feature = "uuid")]
10pub(crate) mod valuuid;
11
12use crate::{
13    PrimaryKey, TableBuilder, TablePrimaryKey,
14    builder::keys::{foreign::ForeignKeyInteger, primary::PrimaryKeyInteger},
15};
16
17use super::keys::{foreign::ForeignKeyIntegerOld, primary::PrimaryKeyIntegerOld};
18
19/// List of Values
20#[derive(Debug, Clone, Default, PartialEq, Eq)]
21pub struct Values {
22    /// List of values
23    pub(crate) values: Vec<(String, Value)>,
24    // /// List of columns in the order they were added
25    // pub(crate) order: Vec<String>,
26}
27
28impl Values {
29    /// Create a new instance of Values
30    pub fn new() -> Self {
31        Values { values: Vec::new() }
32    }
33
34    /// Push a value to the list of values
35    pub fn push(&mut self, column: String, value: impl Into<Value>) {
36        self.values.push((column, value.into()));
37    }
38
39    /// Get a value by index from the list of values
40    pub fn get(&self, column: &String) -> Option<&Value> {
41        self.values
42            .iter()
43            .find_map(|(c, o)| if c == column { Some(o) } else { None })
44    }
45
46    /// Length / Count of the values stored
47    pub fn len(&self) -> usize {
48        self.values.len()
49    }
50
51    /// Check if the values are empty
52    pub fn is_empty(&self) -> bool {
53        self.values.is_empty()
54    }
55}
56
57impl IntoIterator for Values {
58    type Item = Value;
59    type IntoIter = std::vec::IntoIter<Value>;
60
61    fn into_iter(self) -> Self::IntoIter {
62        self.values
63            .into_iter()
64            .map(|(_, v)| v)
65            .collect::<Vec<Value>>()
66            .into_iter()
67    }
68}
69
70/// A value for a column
71#[derive(Debug, Clone, Eq, PartialEq)]
72pub enum Value {
73    /// A text (String) value
74    Text(String),
75    /// An integer (i64) values so the values can be positive or negative
76    Integer(i64),
77    /// A boolean (i64) value (0 or 1)
78    /// This is because SQLite does not have a boolean type
79    Boolean(u8),
80    /// Identifier Key type (Primary / Forigen Key) which is a u64
81    Identifier(u64),
82    /// A binary blob value (vector of bytes)
83    Blob(Vec<u8>),
84    /// JSON blob
85    Json(Vec<u8>),
86    /// A NULL value
87    Null,
88}
89
90impl Default for Value {
91    fn default() -> Self {
92        Value::Text(String::new())
93    }
94}
95
96impl Display for Value {
97    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
98        match self {
99            Value::Text(value) => write!(f, "{}", value),
100            Value::Integer(value) => write!(f, "{}", value),
101            Value::Boolean(value) => write!(f, "{}", value),
102            Value::Identifier(value) => write!(f, "{}", value),
103            Value::Blob(value) | Value::Json(value) => {
104                write!(f, "{}", str::from_utf8(value).unwrap_or(""))
105            }
106            Value::Null => write!(f, "NULL"),
107        }
108    }
109}
110
111impl From<PrimaryKey<String>> for Value {
112    fn from(value: PrimaryKey<String>) -> Self {
113        Value::Text(value.into())
114    }
115}
116
117impl From<&PrimaryKey<String>> for Value {
118    fn from(value: &PrimaryKey<String>) -> Self {
119        Value::Text(value.clone().into())
120    }
121}
122
123impl From<PrimaryKeyInteger> for Value {
124    fn from(value: PrimaryKeyInteger) -> Self {
125        Value::Identifier(u64::from(value))
126    }
127}
128
129impl From<&PrimaryKeyInteger> for Value {
130    fn from(value: &PrimaryKeyInteger) -> Self {
131        Value::Identifier((*value).into())
132    }
133}
134
135impl From<PrimaryKeyIntegerOld> for Value {
136    fn from(value: PrimaryKeyIntegerOld) -> Self {
137        Value::Identifier(value.value as u64)
138    }
139}
140
141impl From<&PrimaryKeyIntegerOld> for Value {
142    fn from(value: &PrimaryKeyIntegerOld) -> Self {
143        Value::Identifier(value.value as u64)
144    }
145}
146
147// Where converting a ForeignKeyInteger to a Value,
148// we only care about the integer value
149impl<T> From<ForeignKeyInteger<T>> for Value
150where
151    T: TableBuilder + TablePrimaryKey,
152{
153    fn from(value: ForeignKeyInteger<T>) -> Self {
154        Value::Identifier(value.key)
155    }
156}
157
158impl<T> From<&ForeignKeyInteger<T>> for Value
159where
160    T: TableBuilder + TablePrimaryKey,
161{
162    fn from(value: &ForeignKeyInteger<T>) -> Self {
163        Value::Identifier(value.key)
164    }
165}
166
167// ForeignKey<i32, T> -> Value
168impl<T> From<ForeignKeyIntegerOld<T>> for Value
169where
170    T: TableBuilder + TablePrimaryKey,
171{
172    fn from(value: ForeignKeyIntegerOld<T>) -> Self {
173        Value::Identifier(value.key as u64)
174    }
175}
176
177// &ForeignKey<i32, T> -> Value
178impl<T> From<&ForeignKeyIntegerOld<T>> for Value
179where
180    T: TableBuilder + TablePrimaryKey,
181{
182    fn from(value: &ForeignKeyIntegerOld<T>) -> Self {
183        Value::Identifier(value.key as u64)
184    }
185}
186
187impl From<String> for Value {
188    fn from(value: String) -> Self {
189        Value::Text(value)
190    }
191}
192
193impl From<&String> for Value {
194    fn from(value: &String) -> Self {
195        Value::Text(value.to_string())
196    }
197}
198
199impl From<&str> for Value {
200    fn from(value: &str) -> Self {
201        Value::Text(value.to_string())
202    }
203}
204
205impl From<bool> for Value {
206    fn from(value: bool) -> Self {
207        Value::Boolean(if value { 1 } else { 0 })
208    }
209}
210
211impl From<&bool> for Value {
212    fn from(value: &bool) -> Self {
213        Value::Boolean(if *value { 1 } else { 0 })
214    }
215}
216
217impl<T> From<Option<T>> for Value
218where
219    T: Into<Value>,
220{
221    fn from(value: Option<T>) -> Self {
222        match value {
223            Some(value) => value.into(),
224            None => Value::Null,
225        }
226    }
227}
228
229impl<T> From<&Option<T>> for Value
230where
231    T: Into<Value> + Clone,
232{
233    fn from(value: &Option<T>) -> Self {
234        match value {
235            Some(value) => value.clone().into(),
236            None => Value::Null,
237        }
238    }
239}
240
241/// This is to make sure we are backwards compatible
242impl From<i32> for Value {
243    fn from(value: i32) -> Self {
244        Value::Integer(value as i64)
245    }
246}
247/// This is to make sure we are backwards compatible
248impl From<&i32> for Value {
249    fn from(value: &i32) -> Self {
250        Value::Integer(*value as i64)
251    }
252}
253
254impl From<u64> for Value {
255    fn from(value: u64) -> Self {
256        Value::Integer(value as i64)
257    }
258}
259
260impl From<&u64> for Value {
261    fn from(value: &u64) -> Self {
262        Value::Integer(*value as i64)
263    }
264}
265
266impl From<i64> for Value {
267    fn from(value: i64) -> Self {
268        Value::Integer(value)
269    }
270}
271
272impl From<usize> for Value {
273    fn from(value: usize) -> Self {
274        Value::Integer(value as i64)
275    }
276}
277
278impl From<Vec<String>> for Value {
279    fn from(value: Vec<String>) -> Self {
280        Value::Blob(serde_json::to_vec(&value).unwrap())
281    }
282}
283
284impl From<&Vec<String>> for Value {
285    fn from(value: &Vec<String>) -> Self {
286        Value::Blob(serde_json::to_vec(value).unwrap())
287    }
288}
289
290impl From<Vec<u8>> for Value {
291    fn from(value: Vec<u8>) -> Self {
292        Value::Blob(value)
293    }
294}
295
296impl From<&Vec<u8>> for Value {
297    fn from(value: &Vec<u8>) -> Self {
298        Value::Blob(value.clone())
299    }
300}
301
302/// Serialize a Value
303impl Serialize for Value {
304    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
305    where
306        S: Serializer,
307    {
308        match self {
309            Value::Text(value) => serializer.serialize_str(value),
310            Value::Integer(value) => serializer.serialize_i64(*value),
311            Value::Boolean(value) => serializer.serialize_u8(*value),
312            Value::Identifier(value) => serializer.serialize_u64(*value),
313            // TODO(geekmasher): This might not be the correct way to serialize a blob
314            Value::Blob(value) => serializer.serialize_bytes(value),
315            // JSON
316            Value::Json(value) => serde_json::from_slice::<serde_json::Value>(value)
317                .map_err(serde::ser::Error::custom)?
318                .serialize(serializer),
319            // NULL
320            Value::Null => serializer.serialize_none(),
321        }
322    }
323}
324
325impl<'de> Deserialize<'de> for Value {
326    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
327    where
328        D: serde::Deserializer<'de>,
329    {
330        struct ValueVisitor;
331
332        impl<'de> serde::de::Visitor<'de> for ValueVisitor {
333            type Value = Value;
334
335            fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
336                formatter.write_str("a value")
337            }
338
339            fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
340            where
341                E: serde::de::Error,
342            {
343                Ok(Value::Text(value.to_string()))
344            }
345
346            fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
347            where
348                E: serde::de::Error,
349            {
350                Ok(Value::Text(v))
351            }
352
353            fn visit_i32<E>(self, value: i32) -> Result<Self::Value, E>
354            where
355                E: serde::de::Error,
356            {
357                Ok(Value::Integer(value as i64))
358            }
359            fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
360            where
361                E: serde::de::Error,
362            {
363                Ok(Value::Integer(v as i64))
364            }
365
366            fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
367            where
368                E: serde::de::Error,
369            {
370                Ok(Value::Integer(value))
371            }
372
373            fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
374            where
375                E: serde::de::Error,
376            {
377                Ok(Value::Integer(value as i64))
378            }
379
380            fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E>
381            where
382                E: serde::de::Error,
383            {
384                Ok(Value::Boolean(if value { 1 } else { 0 }))
385            }
386
387            fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
388            where
389                E: serde::de::Error,
390            {
391                // TODO: is this the correct way to handle blobs?
392                if value.starts_with(b"{") || value.starts_with(b"[") {
393                    Ok(Value::Json(value.to_vec()))
394                } else {
395                    Ok(Value::Blob(value.to_vec()))
396                }
397            }
398
399            fn visit_none<E>(self) -> Result<Self::Value, E>
400            where
401                E: serde::de::Error,
402            {
403                Ok(Value::Null)
404            }
405
406            fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
407            where
408                D: serde::Deserializer<'de>,
409            {
410                Deserialize::deserialize(deserializer)
411            }
412
413            fn visit_map<A>(self, _accessor: A) -> Result<Self::Value, A::Error>
414            where
415                A: serde::de::MapAccess<'de>,
416            {
417                Err(serde::de::Error::custom("Expects a struct"))
418            }
419        }
420
421        deserializer.deserialize_any(ValueVisitor)
422    }
423}
424
425#[cfg(test)]
426mod tests {
427    use super::Values;
428
429    #[test]
430    fn test_values() {
431        let mut values = Values::new();
432        values.push("id".to_string(), 1);
433        values.push("name".to_string(), "Bob");
434
435        assert_eq!(values.len(), 2);
436    }
437}