sqlite_bindings_lunatic/
value.rs1use std::convert::TryFrom;
2
3use {Error, Result};
4
5#[derive(Clone, Debug, PartialEq)]
7pub enum Value {
8 Binary(Vec<u8>),
10 Float(f64),
12 Integer(i64),
14 String(String),
16 Null,
18}
19
20#[derive(Clone, Copy, Debug, Eq, PartialEq)]
22pub enum Type {
23 Binary,
25 Float,
27 Integer,
29 String,
31 Null,
33}
34
35impl Value {
36 pub fn kind(&self) -> Type {
38 match self {
39 &Value::Binary(_) => Type::Binary,
40 &Value::Float(_) => Type::Float,
41 &Value::Integer(_) => Type::Integer,
42 &Value::String(_) => Type::String,
43 &Value::Null => Type::Null,
44 }
45 }
46
47 #[inline]
49 pub fn try_into<'l, T>(&'l self) -> Result<T>
50 where
51 T: TryFrom<&'l Value, Error = Error>,
52 {
53 T::try_from(self)
54 }
55}
56
57macro_rules! implement(
58 ($type:ty, Null) => {
59 impl From<$type> for Value {
60 #[inline]
61 fn from(_: $type) -> Self {
62 Value::Null
63 }
64 }
65 };
66 ($type:ty, $value:ident) => {
67 impl From<$type> for Value {
68 #[inline]
69 fn from(value: $type) -> Self {
70 Value::$value(value.into())
71 }
72 }
73 };
74);
75
76implement!(Vec<u8>, Binary);
77implement!(&[u8], Binary);
78implement!(f64, Float);
79implement!(i64, Integer);
80implement!(String, String);
81implement!(&str, String);
82implement!((), Null);
83
84macro_rules! implement(
85 (@value $type:ty, $value:ident) => {
86 impl TryFrom<Value> for $type {
87 type Error = Error;
88
89 #[inline]
90 fn try_from(value: Value) -> Result<Self> {
91 if let Value::$value(value) = value {
92 return Ok(value);
93 }
94 raise!("failed to convert");
95 }
96 }
97 };
98 (@reference $type:ty, Null) => {
99 impl TryFrom<&Value> for $type {
100 type Error = Error;
101
102 #[inline]
103 fn try_from(value: &Value) -> Result<Self> {
104 if let &Value::Null = value {
105 return Ok(());
106 }
107 raise!("failed to convert");
108 }
109 }
110 };
111 (@reference $type:ty, $value:ident) => {
112 impl TryFrom<&Value> for $type {
113 type Error = Error;
114
115 #[inline]
116 fn try_from(value: &Value) -> Result<Self> {
117 if let &Value::$value(value) = value {
118 return Ok(value);
119 }
120 raise!("failed to convert");
121 }
122 }
123
124 impl TryFrom<&Value> for Option<$type> {
125 type Error = Error;
126
127 #[inline]
128 fn try_from(value: &Value) -> Result<Self> {
129 if let &Value::Null = value {
130 return Ok(None);
131 }
132 <$type>::try_from(value).and_then(|value| Ok(Some(value)))
133 }
134 }
135 };
136 (@reference-lifetime $type:ty, $value:ident) => {
137 impl<'l> TryFrom<&'l Value> for $type {
138 type Error = Error;
139
140 #[inline]
141 fn try_from(value: &'l Value) -> Result<Self> {
142 if let &Value::$value(ref value) = value {
143 return Ok(value);
144 }
145 raise!("failed to convert");
146 }
147 }
148
149 impl<'l> TryFrom<&'l Value> for Option<$type> {
150 type Error = Error;
151
152 #[inline]
153 fn try_from(value: &'l Value) -> Result<Self> {
154 if let Value::Null = value {
155 return Ok(None);
156 }
157 <$type>::try_from(value).and_then(|value| Ok(Some(value)))
158 }
159 }
160 };
161);
162
163implement!(@value Vec<u8>, Binary);
164implement!(@reference-lifetime &'l [u8], Binary);
165implement!(@value String, String);
166implement!(@reference-lifetime &'l str, String);
167implement!(@reference f64, Float);
168implement!(@reference i64, Integer);
169implement!(@reference (), Null);