1use slice::ByteSlice;
2use std::{
3 convert::Into,
4 io::{Error, ErrorKind, Result},
5};
6
7#[derive(Debug, Clone, PartialEq)]
8pub enum Variant {
9 Nil,
10 Bool(bool),
11 Int64(i64),
12 UInt64(u64),
13 Float64(f64),
14 String(Box<str>),
15 BigInt(Box<[u8]>),
16 Buffer(Box<[u8]>),
17 Slice(ByteSlice),
18}
19
20pub trait Value<T> {
22 fn try_into(self) -> Result<T>;
23}
24
25impl Value<String> for Variant {
26 fn try_into(self) -> Result<String> {
27 match self {
28 Variant::String(val) => Ok(val.to_string()),
29 _ => Err(Error::new(ErrorKind::InvalidData, "wrong type")),
30 }
31 }
32}
33
34impl Value<Vec<u8>> for Variant {
35 fn try_into(self) -> Result<Vec<u8>> {
36 match self {
37 Variant::String(val) => Ok(val.to_string().into_bytes()),
38 Variant::Buffer(val) => Ok(val.into_vec()),
39 Variant::Slice(val) => Ok(val.as_ref().to_vec()),
40 _ => Err(Error::new(ErrorKind::InvalidData, "wrong type")),
41 }
42 }
43}
44
45impl Value<ByteSlice> for Variant {
46 fn try_into(self) -> Result<ByteSlice> {
47 match self {
48 Variant::Slice(val) => Ok(val),
49 _ => Err(Error::new(ErrorKind::InvalidData, "wrong type")),
50 }
51 }
52}
53
54impl Value<u64> for Variant {
55 fn try_into(self) -> Result<u64> {
56 match self {
57 Variant::Nil => Ok(0),
58 Variant::Bool(val) => Ok(if val { 1 } else { 0 }),
59 Variant::Int64(val) => Ok(val as u64),
60 Variant::UInt64(val) => Ok(val as u64),
61 Variant::Float64(val) => Ok(val as u64),
62 _ => Err(Error::new(ErrorKind::InvalidData, "wrong type")),
63 }
64 }
65}
66
67impl Value<usize> for Variant {
68 fn try_into(self) -> Result<usize> {
69 Value::<u64>::try_into(self).map(|v| v as usize)
70 }
71}
72
73impl Value<u32> for Variant {
74 fn try_into(self) -> Result<u32> {
75 Value::<u64>::try_into(self).map(|v| v as u32)
76 }
77}
78
79impl Value<u16> for Variant {
80 fn try_into(self) -> Result<u16> {
81 Value::<u64>::try_into(self).map(|v| v as u16)
82 }
83}
84
85impl Value<u8> for Variant {
86 fn try_into(self) -> Result<u8> {
87 Value::<u64>::try_into(self).map(|v| v as u8)
88 }
89}
90
91impl Value<i64> for Variant {
92 fn try_into(self) -> Result<i64> {
93 match self {
94 Variant::Nil => Ok(0),
95 Variant::Bool(val) => Ok(if val { 1 } else { 0 }),
96 Variant::Int64(val) => Ok(val as i64),
97 Variant::UInt64(val) => Ok(val as i64),
98 Variant::Float64(val) => Ok(val as i64),
99 _ => Err(Error::new(ErrorKind::InvalidData, "wrong type")),
100 }
101 }
102}
103
104impl Value<isize> for Variant {
105 fn try_into(self) -> Result<isize> {
106 Value::<i64>::try_into(self).map(|v| v as isize)
107 }
108}
109
110impl Value<i32> for Variant {
111 fn try_into(self) -> Result<i32> {
112 Value::<i64>::try_into(self).map(|v| v as i32)
113 }
114}
115
116impl Value<i16> for Variant {
117 fn try_into(self) -> Result<i16> {
118 Value::<i64>::try_into(self).map(|v| v as i16)
119 }
120}
121
122impl Value<i8> for Variant {
123 fn try_into(self) -> Result<i8> {
124 Value::<i64>::try_into(self).map(|v| v as i8)
125 }
126}
127
128impl Value<f64> for Variant {
129 fn try_into(self) -> Result<f64> {
130 match self {
131 Variant::Nil => Ok(0f64),
132 Variant::Bool(val) => Ok(if val { 1f64 } else { 0f64 }),
133 Variant::Int64(val) => Ok(val as f64),
134 Variant::UInt64(val) => Ok(val as f64),
135 Variant::Float64(val) => Ok(val as f64),
136 _ => Err(Error::new(ErrorKind::InvalidData, "wrong type")),
137 }
138 }
139}
140
141impl Value<f32> for Variant {
142 fn try_into(self) -> Result<f32> {
143 Value::<f64>::try_into(self).map(|v| v as f32)
144 }
145}
146
147impl Into<Variant> for bool {
148 fn into(self) -> Variant {
149 Variant::Bool(self)
150 }
151}
152
153impl Into<Variant> for i8 {
154 fn into(self) -> Variant {
155 Variant::Int64(i64::from(self))
156 }
157}
158
159impl Into<Variant> for i16 {
160 fn into(self) -> Variant {
161 Variant::Int64(i64::from(self))
162 }
163}
164
165impl Into<Variant> for i32 {
166 fn into(self) -> Variant {
167 Variant::Int64(i64::from(self))
168 }
169}
170
171impl Into<Variant> for i64 {
172 fn into(self) -> Variant {
173 Variant::Int64(self)
174 }
175}
176
177impl Into<Variant> for u8 {
178 fn into(self) -> Variant {
179 Variant::UInt64(u64::from(self))
180 }
181}
182
183impl Into<Variant> for u16 {
184 fn into(self) -> Variant {
185 Variant::UInt64(u64::from(self))
186 }
187}
188
189impl Into<Variant> for u32 {
190 fn into(self) -> Variant {
191 Variant::UInt64(u64::from(self))
192 }
193}
194
195impl Into<Variant> for u64 {
196 fn into(self) -> Variant {
197 Variant::UInt64(self)
198 }
199}
200
201impl Into<Variant> for f32 {
202 fn into(self) -> Variant {
203 Variant::Float64(f64::from(self))
204 }
205}
206
207impl Into<Variant> for f64 {
208 fn into(self) -> Variant {
209 Variant::Float64(self)
210 }
211}
212
213impl Into<Variant> for Box<str> {
214 fn into(self) -> Variant {
215 Variant::String(self)
216 }
217}
218
219impl Into<Variant> for Box<[u8]> {
220 fn into(self) -> Variant {
221 Variant::Buffer(self)
222 }
223}
224
225impl Into<Variant> for ByteSlice {
226 fn into(self) -> Variant {
227 Variant::Slice(self)
228 }
229}