Skip to main content

fletch_orm/
value.rs

1//! Dynamic value type for bind parameters.
2
3/// A dynamically-typed database value used for bind parameters.
4#[derive(Debug, Clone, PartialEq)]
5pub enum Value {
6    /// A null value.
7    Null,
8    /// A boolean value.
9    Bool(bool),
10    /// A 32-bit integer.
11    I32(i32),
12    /// A 64-bit integer.
13    I64(i64),
14    /// A 32-bit float.
15    F32(f32),
16    /// A 64-bit float.
17    F64(f64),
18    /// A text string.
19    Text(String),
20    /// Raw bytes.
21    Bytes(Vec<u8>),
22    /// A UUID value.
23    #[cfg(feature = "uuid")]
24    Uuid(uuid::Uuid),
25    /// A JSON value.
26    #[cfg(feature = "json")]
27    Json(serde_json::Value),
28    /// A UTC timestamp.
29    #[cfg(feature = "chrono")]
30    Timestamp(chrono::DateTime<chrono::Utc>),
31}
32
33impl From<bool> for Value {
34    fn from(v: bool) -> Self {
35        Self::Bool(v)
36    }
37}
38
39impl From<i32> for Value {
40    fn from(v: i32) -> Self {
41        Self::I32(v)
42    }
43}
44
45impl From<i64> for Value {
46    fn from(v: i64) -> Self {
47        Self::I64(v)
48    }
49}
50
51impl From<f32> for Value {
52    fn from(v: f32) -> Self {
53        Self::F32(v)
54    }
55}
56
57impl From<f64> for Value {
58    fn from(v: f64) -> Self {
59        Self::F64(v)
60    }
61}
62
63impl From<String> for Value {
64    fn from(v: String) -> Self {
65        Self::Text(v)
66    }
67}
68
69impl From<&str> for Value {
70    fn from(v: &str) -> Self {
71        Self::Text(v.to_owned())
72    }
73}
74
75impl From<Vec<u8>> for Value {
76    fn from(v: Vec<u8>) -> Self {
77        Self::Bytes(v)
78    }
79}
80
81#[cfg(feature = "uuid")]
82impl From<uuid::Uuid> for Value {
83    fn from(v: uuid::Uuid) -> Self {
84        Self::Uuid(v)
85    }
86}
87
88#[cfg(feature = "json")]
89impl From<serde_json::Value> for Value {
90    fn from(v: serde_json::Value) -> Self {
91        Self::Json(v)
92    }
93}
94
95#[cfg(feature = "chrono")]
96impl From<chrono::DateTime<chrono::Utc>> for Value {
97    fn from(v: chrono::DateTime<chrono::Utc>) -> Self {
98        Self::Timestamp(v)
99    }
100}
101
102impl<T: Into<Self>> From<Option<T>> for Value {
103    fn from(v: Option<T>) -> Self {
104        match v {
105            Some(v) => v.into(),
106            None => Self::Null,
107        }
108    }
109}
110
111#[cfg(test)]
112mod tests {
113    use super::*;
114
115    #[test]
116    fn bool_from_impl() {
117        assert_eq!(Value::from(true), Value::Bool(true));
118    }
119
120    #[cfg(feature = "uuid")]
121    #[test]
122    fn uuid_from_impl() {
123        let id = uuid::Uuid::nil();
124        assert_eq!(Value::from(id), Value::Uuid(id));
125    }
126
127    #[cfg(feature = "json")]
128    #[test]
129    fn json_from_impl() {
130        let v = serde_json::json!({"key": "value"});
131        assert_eq!(Value::from(v.clone()), Value::Json(v));
132    }
133
134    #[cfg(feature = "chrono")]
135    #[test]
136    fn timestamp_from_impl() {
137        let ts = chrono::Utc::now();
138        assert_eq!(Value::from(ts), Value::Timestamp(ts));
139    }
140}