1use super::{Null, Type};
2
3#[derive(Clone, Debug, PartialEq)]
9pub enum Value {
10 Null,
12 Integer(i64),
14 Real(f64),
16 Text(String),
18 Blob(Vec<u8>),
20}
21
22impl From<Null> for Value {
23 #[inline]
24 fn from(_: Null) -> Self {
25 Self::Null
26 }
27}
28
29impl From<bool> for Value {
30 #[inline]
31 fn from(i: bool) -> Self {
32 Self::Integer(i as i64)
33 }
34}
35
36impl From<isize> for Value {
37 #[inline]
38 fn from(i: isize) -> Self {
39 Self::Integer(i as i64)
40 }
41}
42
43#[cfg(feature = "i128_blob")]
44impl From<i128> for Value {
45 #[inline]
46 fn from(i: i128) -> Self {
47 Self::Blob(i128::to_be_bytes(i ^ (1_i128 << 127)).to_vec())
50 }
51}
52
53#[cfg(feature = "uuid")]
54impl From<uuid::Uuid> for Value {
55 #[inline]
56 fn from(id: uuid::Uuid) -> Self {
57 Self::Blob(id.as_bytes().to_vec())
58 }
59}
60
61macro_rules! from_i64(
62 ($t:ty) => (
63 impl From<$t> for Value {
64 #[inline]
65 fn from(i: $t) -> Value {
66 Value::Integer(i64::from(i))
67 }
68 }
69 )
70);
71
72from_i64!(i8);
73from_i64!(i16);
74from_i64!(i32);
75from_i64!(u8);
76from_i64!(u16);
77from_i64!(u32);
78
79impl From<i64> for Value {
80 #[inline]
81 fn from(i: i64) -> Self {
82 Self::Integer(i)
83 }
84}
85
86impl From<f32> for Value {
87 #[inline]
88 fn from(f: f32) -> Self {
89 Self::Real(f.into())
90 }
91}
92
93impl From<f64> for Value {
94 #[inline]
95 fn from(f: f64) -> Self {
96 Self::Real(f)
97 }
98}
99
100impl From<String> for Value {
101 #[inline]
102 fn from(s: String) -> Self {
103 Self::Text(s)
104 }
105}
106
107impl From<Vec<u8>> for Value {
108 #[inline]
109 fn from(v: Vec<u8>) -> Self {
110 Self::Blob(v)
111 }
112}
113
114impl<T> From<Option<T>> for Value
115where
116 T: Into<Self>,
117{
118 #[inline]
119 fn from(v: Option<T>) -> Self {
120 match v {
121 Some(x) => x.into(),
122 None => Self::Null,
123 }
124 }
125}
126
127impl Value {
128 #[inline]
130 #[must_use]
131 pub fn data_type(&self) -> Type {
132 match *self {
133 Self::Null => Type::Null,
134 Self::Integer(_) => Type::Integer,
135 Self::Real(_) => Type::Real,
136 Self::Text(_) => Type::Text,
137 Self::Blob(_) => Type::Blob,
138 }
139 }
140}
141
142#[cfg(test)]
143mod test {
144 use super::Value;
145 use crate::types::Type;
146
147 #[test]
148 fn from() {
149 assert_eq!(Value::from(2f32), Value::Real(2f64));
150 assert_eq!(Value::from(3.), Value::Real(3.));
151 assert_eq!(Value::from(vec![0u8]), Value::Blob(vec![0u8]));
152 }
153
154 #[test]
155 fn data_type() {
156 assert_eq!(Value::Null.data_type(), Type::Null);
157 assert_eq!(Value::Integer(0).data_type(), Type::Integer);
158 assert_eq!(Value::Real(0.).data_type(), Type::Real);
159 assert_eq!(Value::Text(String::new()).data_type(), Type::Text);
160 assert_eq!(Value::Blob(vec![]).data_type(), Type::Blob);
161 }
162
163 #[test]
164 fn from_option() {
165 assert_eq!(Value::from(None as Option<i64>), Value::Null);
166 assert_eq!(Value::from(Some(0)), Value::Integer(0));
167 }
168}