cassandra_protocol/types/
value.rs

1use std::cmp::Eq;
2use std::collections::{BTreeMap, HashMap};
3use std::convert::Into;
4use std::fmt::Debug;
5use std::hash::Hash;
6use std::net::IpAddr;
7use std::num::{NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8};
8
9use chrono::prelude::*;
10use num_bigint::BigInt;
11use time::PrimitiveDateTime;
12use uuid::Uuid;
13
14use super::blob::Blob;
15use super::decimal::Decimal;
16use super::duration::Duration;
17use super::*;
18use crate::Error;
19
20const NULL_INT_VALUE: i32 = -1;
21const NOT_SET_INT_VALUE: i32 = -2;
22
23/// Cassandra value which could be an array of bytes, null and non-set values.
24#[derive(Debug, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
25pub enum Value {
26    Some(Vec<u8>),
27    Null,
28    NotSet,
29}
30
31impl Value {
32    pub fn new<B>(v: B) -> Value
33    where
34        B: Into<Bytes>,
35    {
36        Value::Some(v.into().0)
37    }
38}
39
40impl Serialize for Value {
41    fn serialize(&self, cursor: &mut Cursor<&mut Vec<u8>>, version: Version) {
42        match self {
43            Value::Null => NULL_INT_VALUE.serialize(cursor, version),
44            Value::NotSet => NOT_SET_INT_VALUE.serialize(cursor, version),
45            Value::Some(value) => {
46                let len = value.len() as CInt;
47                len.serialize(cursor, version);
48                value.serialize(cursor, version);
49            }
50        }
51    }
52}
53
54impl FromCursor for Value {
55    fn from_cursor(cursor: &mut Cursor<&[u8]>, _version: Version) -> Result<Value, Error> {
56        let value_size = {
57            let mut buff = [0; INT_LEN];
58            cursor.read_exact(&mut buff)?;
59            CInt::from_be_bytes(buff)
60        };
61
62        if value_size > 0 {
63            Ok(Value::Some(cursor_next_value(cursor, value_size as usize)?))
64        } else if value_size == -1 {
65            Ok(Value::Null)
66        } else if value_size == -2 {
67            Ok(Value::NotSet)
68        } else {
69            Err(Error::General("Could not decode query values".into()))
70        }
71    }
72}
73
74// We are assuming here primitive value serialization will not change across protocol versions,
75// which gives us simpler user API.
76
77impl<T: Into<Bytes>> From<T> for Value {
78    fn from(b: T) -> Value {
79        Value::new(b.into())
80    }
81}
82
83impl<T: Into<Bytes>> From<Option<T>> for Value {
84    fn from(b: Option<T>) -> Value {
85        match b {
86            Some(b) => Value::new(b.into()),
87            None => Value::Null,
88        }
89    }
90}
91
92#[derive(Debug, Clone, Constructor)]
93pub struct Bytes(Vec<u8>);
94
95impl Bytes {
96    /// Consumes `Bytes` and returns the inner `Vec<u8>`
97    pub fn into_inner(self) -> Vec<u8> {
98        self.0
99    }
100}
101
102impl From<String> for Bytes {
103    #[inline]
104    fn from(value: String) -> Self {
105        Bytes(value.into_bytes())
106    }
107}
108
109impl From<&str> for Bytes {
110    #[inline]
111    fn from(value: &str) -> Self {
112        Bytes(value.as_bytes().to_vec())
113    }
114}
115
116impl From<i8> for Bytes {
117    #[inline]
118    fn from(value: i8) -> Self {
119        Bytes(vec![value as u8])
120    }
121}
122
123impl From<i16> for Bytes {
124    #[inline]
125    fn from(value: i16) -> Self {
126        Bytes(to_short(value))
127    }
128}
129
130impl From<i32> for Bytes {
131    #[inline]
132    fn from(value: i32) -> Self {
133        Bytes(to_int(value))
134    }
135}
136
137impl From<i64> for Bytes {
138    #[inline]
139    fn from(value: i64) -> Self {
140        Bytes(to_bigint(value))
141    }
142}
143
144impl From<u8> for Bytes {
145    #[inline]
146    fn from(value: u8) -> Self {
147        Bytes(vec![value])
148    }
149}
150
151impl From<u16> for Bytes {
152    #[inline]
153    fn from(value: u16) -> Self {
154        Bytes(to_u_short(value))
155    }
156}
157
158impl From<u32> for Bytes {
159    #[inline]
160    fn from(value: u32) -> Self {
161        Bytes(to_u_int(value))
162    }
163}
164
165impl From<u64> for Bytes {
166    #[inline]
167    fn from(value: u64) -> Self {
168        Bytes(to_u_big(value))
169    }
170}
171
172impl From<NonZeroI8> for Bytes {
173    #[inline]
174    fn from(value: NonZeroI8) -> Self {
175        value.get().into()
176    }
177}
178
179impl From<NonZeroI16> for Bytes {
180    #[inline]
181    fn from(value: NonZeroI16) -> Self {
182        value.get().into()
183    }
184}
185
186impl From<NonZeroI32> for Bytes {
187    #[inline]
188    fn from(value: NonZeroI32) -> Self {
189        value.get().into()
190    }
191}
192
193impl From<NonZeroI64> for Bytes {
194    #[inline]
195    fn from(value: NonZeroI64) -> Self {
196        value.get().into()
197    }
198}
199
200impl From<bool> for Bytes {
201    #[inline]
202    fn from(value: bool) -> Self {
203        if value {
204            Bytes(vec![1])
205        } else {
206            Bytes(vec![0])
207        }
208    }
209}
210
211impl From<Uuid> for Bytes {
212    #[inline]
213    fn from(value: Uuid) -> Self {
214        Bytes(value.as_bytes().to_vec())
215    }
216}
217
218impl From<IpAddr> for Bytes {
219    #[inline]
220    fn from(value: IpAddr) -> Self {
221        match value {
222            IpAddr::V4(ip) => Bytes(ip.octets().to_vec()),
223            IpAddr::V6(ip) => Bytes(ip.octets().to_vec()),
224        }
225    }
226}
227
228impl From<f32> for Bytes {
229    #[inline]
230    fn from(value: f32) -> Self {
231        Bytes(to_float(value))
232    }
233}
234
235impl From<f64> for Bytes {
236    #[inline]
237    fn from(value: f64) -> Self {
238        Bytes(to_float_big(value))
239    }
240}
241
242impl From<PrimitiveDateTime> for Bytes {
243    #[inline]
244    fn from(value: PrimitiveDateTime) -> Self {
245        let ts: i64 =
246            value.assume_utc().unix_timestamp() * 1_000 + value.nanosecond() as i64 / 1_000_000;
247        Bytes(to_bigint(ts))
248    }
249}
250
251impl From<Blob> for Bytes {
252    #[inline]
253    fn from(value: Blob) -> Self {
254        Bytes(value.into_vec())
255    }
256}
257
258impl From<Decimal> for Bytes {
259    #[inline]
260    fn from(value: Decimal) -> Self {
261        Bytes(value.serialize_to_vec(Version::V4))
262    }
263}
264
265impl From<NaiveDateTime> for Bytes {
266    #[inline]
267    fn from(value: NaiveDateTime) -> Self {
268        value.and_utc().timestamp_millis().into()
269    }
270}
271
272impl From<DateTime<Utc>> for Bytes {
273    #[inline]
274    fn from(value: DateTime<Utc>) -> Self {
275        value.timestamp_millis().into()
276    }
277}
278
279impl From<Duration> for Bytes {
280    #[inline]
281    fn from(value: Duration) -> Self {
282        Bytes(value.serialize_to_vec(Version::V5))
283    }
284}
285
286impl<T: Into<Bytes>> From<Vec<T>> for Bytes {
287    fn from(vec: Vec<T>) -> Bytes {
288        let mut bytes = Vec::with_capacity(INT_LEN);
289        let len = vec.len() as CInt;
290
291        bytes.extend_from_slice(&len.to_be_bytes());
292
293        let mut cursor = Cursor::new(&mut bytes);
294        cursor.set_position(INT_LEN as u64);
295
296        for v in vec {
297            let b: Bytes = v.into();
298            Value::new(b).serialize(&mut cursor, Version::V4);
299        }
300
301        Bytes(bytes)
302    }
303}
304
305impl From<BigInt> for Bytes {
306    fn from(value: BigInt) -> Self {
307        Self(value.serialize_to_vec(Version::V4))
308    }
309}
310
311impl<K, V> From<HashMap<K, V>> for Bytes
312where
313    K: Into<Bytes> + Hash + Eq,
314    V: Into<Bytes>,
315{
316    fn from(map: HashMap<K, V>) -> Bytes {
317        let mut bytes = Vec::with_capacity(INT_LEN);
318        let len = map.len() as CInt;
319
320        bytes.extend_from_slice(&len.to_be_bytes());
321
322        let mut cursor = Cursor::new(&mut bytes);
323        cursor.set_position(INT_LEN as u64);
324
325        for (k, v) in map {
326            let key_bytes: Bytes = k.into();
327            let val_bytes: Bytes = v.into();
328
329            Value::new(key_bytes).serialize(&mut cursor, Version::V4);
330            Value::new(val_bytes).serialize(&mut cursor, Version::V4);
331        }
332
333        Bytes(bytes)
334    }
335}
336
337impl<K, V> From<BTreeMap<K, V>> for Bytes
338where
339    K: Into<Bytes> + Hash + Eq,
340    V: Into<Bytes>,
341{
342    fn from(map: BTreeMap<K, V>) -> Bytes {
343        let mut bytes = Vec::with_capacity(INT_LEN);
344        let len = map.len() as CInt;
345
346        bytes.extend_from_slice(&len.to_be_bytes());
347
348        let mut cursor = Cursor::new(&mut bytes);
349        cursor.set_position(INT_LEN as u64);
350
351        for (k, v) in map {
352            let key_bytes: Bytes = k.into();
353            let val_bytes: Bytes = v.into();
354
355            Value::new(key_bytes).serialize(&mut cursor, Version::V4);
356            Value::new(val_bytes).serialize(&mut cursor, Version::V4);
357        }
358
359        Bytes(bytes)
360    }
361}
362
363#[cfg(test)]
364mod tests {
365    use super::*;
366
367    #[test]
368    fn test_value_serialization() {
369        assert_eq!(
370            Value::Some(vec![1]).serialize_to_vec(Version::V4),
371            vec![0, 0, 0, 1, 1]
372        );
373
374        assert_eq!(
375            Value::Some(vec![1, 2, 3]).serialize_to_vec(Version::V4),
376            vec![0, 0, 0, 3, 1, 2, 3]
377        );
378
379        assert_eq!(
380            Value::Null.serialize_to_vec(Version::V4),
381            vec![255, 255, 255, 255]
382        );
383        assert_eq!(
384            Value::NotSet.serialize_to_vec(Version::V4),
385            vec![255, 255, 255, 254]
386        )
387    }
388
389    #[test]
390    fn test_new_value_all_types() {
391        assert_eq!(
392            Value::new("hello"),
393            Value::Some(vec!(104, 101, 108, 108, 111))
394        );
395        assert_eq!(
396            Value::new("hello".to_string()),
397            Value::Some(vec!(104, 101, 108, 108, 111))
398        );
399        assert_eq!(Value::new(1_u8), Value::Some(vec!(1)));
400        assert_eq!(Value::new(1_u16), Value::Some(vec!(0, 1)));
401        assert_eq!(Value::new(1_u32), Value::Some(vec!(0, 0, 0, 1)));
402        assert_eq!(Value::new(1_u64), Value::Some(vec!(0, 0, 0, 0, 0, 0, 0, 1)));
403        assert_eq!(Value::new(1_i8), Value::Some(vec!(1)));
404        assert_eq!(Value::new(1_i16), Value::Some(vec!(0, 1)));
405        assert_eq!(Value::new(1_i32), Value::Some(vec!(0, 0, 0, 1)));
406        assert_eq!(Value::new(1_i64), Value::Some(vec!(0, 0, 0, 0, 0, 0, 0, 1)));
407        assert_eq!(Value::new(true), Value::Some(vec!(1)));
408        assert_eq!(
409            Value::new(Duration::new(100, 200, 300).unwrap()),
410            Value::Some(vec!(200, 1, 144, 3, 216, 4))
411        );
412    }
413}