cassandra_proto/types/
value.rs

1use std::cmp::Eq;
2use std::collections::HashMap;
3use std::convert::Into;
4use std::fmt::Debug;
5use std::hash::Hash;
6use std::net::IpAddr;
7
8use crate::frame::IntoBytes;
9use time::Timespec;
10use uuid::Uuid;
11
12use super::blob::Blob;
13use super::decimal::Decimal;
14use super::*;
15
16/// Types of Cassandra value: normal value (bits), null value and not-set value
17#[derive(Debug, Clone)]
18pub enum ValueType {
19    Normal(i32),
20    Null,
21    NotSet,
22}
23
24impl IntoBytes for ValueType {
25    fn into_cbytes(&self) -> Vec<u8> {
26        match *self {
27            ValueType::Normal(n) => to_int(n),
28            ValueType::Null => i_to_n_bytes(-1, INT_LEN),
29            ValueType::NotSet => i_to_n_bytes(-2, INT_LEN),
30        }
31    }
32}
33
34/// Cassandra value which could be an array of bytes, null and non-set values.
35#[derive(Debug, Clone)]
36pub struct Value {
37    pub body: Vec<u8>,
38    pub value_type: ValueType,
39}
40
41impl Value {
42    /// The factory method which creates a normal type value basing on provided bytes.
43    pub fn new_normal<B>(v: B) -> Value
44    where
45        B: Into<Bytes>,
46    {
47        let bytes = v.into().0;
48        let l = bytes.len() as i32;
49        Value {
50            body: bytes,
51            value_type: ValueType::Normal(l),
52        }
53    }
54
55    /// The factory method which creates null Cassandra value.
56    pub fn new_null() -> Value {
57        Value {
58            body: vec![],
59            value_type: ValueType::Null,
60        }
61    }
62
63    /// The factory method which creates non-set Cassandra value.
64    pub fn new_not_set() -> Value {
65        Value {
66            body: vec![],
67            value_type: ValueType::NotSet,
68        }
69    }
70}
71
72impl IntoBytes for Value {
73    fn into_cbytes(&self) -> Vec<u8> {
74        let mut v = Vec::with_capacity(INT_LEN + self.body.len());
75        v.extend_from_slice(self.value_type.into_cbytes().as_slice());
76        v.extend_from_slice(self.body.as_slice());
77        v
78    }
79}
80
81impl<T: Into<Bytes>> From<T> for Value {
82    fn from(b: T) -> Value {
83        Value::new_normal(b.into())
84    }
85}
86
87impl<T: Into<Bytes>> From<Option<T>> for Value {
88    fn from(b: Option<T>) -> Value {
89        match b {
90            Some(b) => Value::new_normal(b.into()),
91            None => Value::new_null(),
92        }
93    }
94}
95
96#[derive(Debug, Clone)]
97pub struct Bytes(Vec<u8>);
98
99impl Bytes {
100    pub fn new(bytes: Vec<u8>) -> Bytes {
101        Bytes(bytes)
102    }
103}
104
105impl Into<Bytes> for String {
106    fn into(self) -> Bytes {
107        Bytes(self.into_bytes())
108    }
109}
110
111impl<'a> Into<Bytes> for &'a str {
112    fn into(self) -> Bytes {
113        Bytes(self.as_bytes().to_vec())
114    }
115}
116
117impl Into<Bytes> for i8 {
118    fn into(self) -> Bytes {
119        Bytes(vec![self as u8])
120    }
121}
122
123impl Into<Bytes> for i16 {
124    fn into(self) -> Bytes {
125        Bytes(to_short(self))
126    }
127}
128
129impl Into<Bytes> for i32 {
130    fn into(self) -> Bytes {
131        Bytes(to_int(self))
132    }
133}
134
135impl Into<Bytes> for i64 {
136    fn into(self) -> Bytes {
137        Bytes(to_bigint(self))
138    }
139}
140
141impl Into<Bytes> for u8 {
142    fn into(self) -> Bytes {
143        Bytes(vec![self])
144    }
145}
146
147impl Into<Bytes> for u16 {
148    fn into(self) -> Bytes {
149        Bytes(to_u_short(self))
150    }
151}
152
153impl Into<Bytes> for u32 {
154    fn into(self) -> Bytes {
155        Bytes(to_u(self))
156    }
157}
158
159impl Into<Bytes> for u64 {
160    fn into(self) -> Bytes {
161        Bytes(to_u_big(self))
162    }
163}
164
165impl Into<Bytes> for bool {
166    fn into(self) -> Bytes {
167        if self {
168            Bytes(vec![1])
169        } else {
170            Bytes(vec![0])
171        }
172    }
173}
174
175impl Into<Bytes> for Uuid {
176    fn into(self) -> Bytes {
177        Bytes(self.as_bytes().to_vec())
178    }
179}
180
181impl Into<Bytes> for IpAddr {
182    fn into(self) -> Bytes {
183        match self {
184            IpAddr::V4(ip) => Bytes(ip.octets().to_vec()),
185            IpAddr::V6(ip) => Bytes(ip.octets().to_vec()),
186        }
187    }
188}
189
190impl Into<Bytes> for f32 {
191    fn into(self) -> Bytes {
192        Bytes(to_float(self))
193    }
194}
195
196impl Into<Bytes> for f64 {
197    fn into(self) -> Bytes {
198        Bytes(to_float_big(self))
199    }
200}
201
202impl Into<Bytes> for Timespec {
203    fn into(self) -> Bytes {
204        let ts: i64 = self.sec * 1_000 + self.nsec as i64 / 1_000_000;
205        Bytes(to_bigint(ts))
206    }
207}
208
209impl Into<Bytes> for Blob {
210    fn into(self) -> Bytes {
211        Bytes(self.into_vec())
212    }
213}
214
215impl Into<Bytes> for Decimal {
216    fn into(self) -> Bytes {
217        Bytes(self.into_cbytes())
218    }
219}
220
221impl<T: Into<Bytes> + Clone + Debug> From<Vec<T>> for Bytes {
222    fn from(vec: Vec<T>) -> Bytes {
223        let mut bytes: Vec<u8> = vec![];
224        bytes.extend_from_slice(to_int(vec.len() as i32).as_slice());
225        bytes = vec.iter().fold(bytes, |mut acc, v| {
226            let b: Bytes = v.clone().into();
227            acc.extend_from_slice(Value::new_normal(b).into_cbytes().as_slice());
228            acc
229        });
230        Bytes(bytes)
231    }
232}
233
234impl<K, V> From<HashMap<K, V>> for Bytes
235where
236    K: Into<Bytes> + Clone + Debug + Hash + Eq,
237    V: Into<Bytes> + Clone + Debug,
238{
239    fn from(map: HashMap<K, V>) -> Bytes {
240        let mut bytes: Vec<u8> = vec![];
241        bytes.extend_from_slice(to_int(map.len() as i32).as_slice());
242        bytes = map.iter().fold(bytes, |mut acc, (k, v)| {
243            let key_bytes: Bytes = k.clone().into();
244            let val_bytes: Bytes = v.clone().into();
245            acc.extend_from_slice(Value::new_normal(key_bytes).into_cbytes().as_slice());
246            acc.extend_from_slice(Value::new_normal(val_bytes).into_cbytes().as_slice());
247            acc
248        });
249        Bytes(bytes)
250    }
251}
252
253#[cfg(test)]
254mod tests {
255
256    use super::*;
257    use crate::frame::traits::IntoBytes;
258
259    #[test]
260    fn test_value_type_into_cbytes() {
261        // normal value types
262        let normal_type = ValueType::Normal(1);
263        assert_eq!(normal_type.into_cbytes(), vec![0, 0, 0, 1]);
264        // null value types
265        let null_type = ValueType::Null;
266        assert_eq!(null_type.into_cbytes(), vec![255, 255, 255, 255]);
267        // not set value types
268        let not_set = ValueType::NotSet;
269        assert_eq!(not_set.into_cbytes(), vec![255, 255, 255, 254])
270    }
271
272    #[test]
273    fn test_new_normal_value() {
274        let plain_value = "hello";
275        let len = plain_value.len() as i32;
276        let normal_value = Value::new_normal(plain_value);
277        assert_eq!(normal_value.body, b"hello");
278        match normal_value.value_type {
279            ValueType::Normal(l) => assert_eq!(l, len),
280            _ => unreachable!(),
281        }
282    }
283
284    #[test]
285    fn test_new_normal_value_all_types() {
286        let _ = Value::new_normal("hello");
287        let _ = Value::new_normal("hello".to_string());
288        let _ = Value::new_normal(1 as u8);
289        let _ = Value::new_normal(1 as u16);
290        let _ = Value::new_normal(1 as u32);
291        let _ = Value::new_normal(1 as u64);
292        let _ = Value::new_normal(1 as i8);
293        let _ = Value::new_normal(1 as i16);
294        let _ = Value::new_normal(1 as i32);
295        let _ = Value::new_normal(1 as i64);
296        let _ = Value::new_normal(true);
297    }
298
299    #[test]
300    fn test_new_null_value() {
301        let null_value = Value::new_null();
302        assert_eq!(null_value.body, vec![]);
303        match null_value.value_type {
304            ValueType::Null => assert!(true),
305            _ => unreachable!(),
306        }
307    }
308
309    #[test]
310    fn test_new_not_set_value() {
311        let not_set_value = Value::new_not_set();
312        assert_eq!(not_set_value.body, vec![]);
313        match not_set_value.value_type {
314            ValueType::NotSet => assert!(true),
315            _ => unreachable!(),
316        }
317    }
318
319    #[test]
320    fn test_value_into_cbytes() {
321        let value = Value::new_normal(1 as u8);
322        assert_eq!(value.into_cbytes(), vec![0, 0, 0, 1, 1]);
323    }
324
325}