sqlite_bindings_lunatic/
value.rs

1use std::convert::TryFrom;
2
3use {Error, Result};
4
5/// A value.
6#[derive(Clone, Debug, PartialEq)]
7pub enum Value {
8    /// Binary data.
9    Binary(Vec<u8>),
10    /// A floating-point number.
11    Float(f64),
12    /// An integer number.
13    Integer(i64),
14    /// A string.
15    String(String),
16    /// A null value.
17    Null,
18}
19
20/// The type of a value.
21#[derive(Clone, Copy, Debug, Eq, PartialEq)]
22pub enum Type {
23    /// The binary type.
24    Binary,
25    /// The floating-point type.
26    Float,
27    /// The integer type.
28    Integer,
29    /// The string type.
30    String,
31    /// The null type.
32    Null,
33}
34
35impl Value {
36    /// Return the type.
37    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    /// Try to return the value.
48    #[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);