toasty_core/stmt/
value_record.rs

1use super::Value;
2
3use std::{hash::Hash, ops};
4
5/// An ordered sequence of [`Value`]s representing a record (row).
6///
7/// `ValueRecord` stores the field values of a single record. It dereferences
8/// to `[Value]`, so slice methods like `len()`, `iter()`, and indexing work
9/// directly.
10///
11/// # Examples
12///
13/// ```
14/// use toasty_core::stmt::{Value, ValueRecord};
15///
16/// let record = ValueRecord::from_vec(vec![Value::from(1_i64), Value::from("alice")]);
17/// assert_eq!(record.len(), 2);
18/// assert_eq!(record[0], 1_i64);
19/// assert_eq!(record[1], "alice");
20/// ```
21#[derive(Debug, Default, Clone, Eq)]
22pub struct ValueRecord {
23    /// The field values in this record, ordered by field index.
24    pub fields: Vec<Value>,
25}
26
27impl ValueRecord {
28    /// Creates a `ValueRecord` from a vector of field values.
29    ///
30    /// # Examples
31    ///
32    /// ```
33    /// # use toasty_core::stmt::{Value, ValueRecord};
34    /// let record = ValueRecord::from_vec(vec![Value::from(42_i64)]);
35    /// assert_eq!(record.len(), 1);
36    /// ```
37    pub fn from_vec(fields: Vec<Value>) -> Self {
38        Self { fields }
39    }
40
41    /// Returns the fields as a slice of [`Value`]s.
42    pub fn as_slice(&self) -> &[Value] {
43        &self[..]
44    }
45}
46
47impl ops::Deref for ValueRecord {
48    type Target = [Value];
49
50    fn deref(&self) -> &Self::Target {
51        &self.fields[..]
52    }
53}
54
55impl ops::DerefMut for ValueRecord {
56    fn deref_mut(&mut self) -> &mut Self::Target {
57        &mut self.fields[..]
58    }
59}
60
61impl IntoIterator for ValueRecord {
62    type Item = Value;
63    type IntoIter = std::vec::IntoIter<Value>;
64
65    fn into_iter(self) -> Self::IntoIter {
66        self.fields.into_iter()
67    }
68}
69
70impl<'a> IntoIterator for &'a ValueRecord {
71    type Item = &'a Value;
72    type IntoIter = std::slice::Iter<'a, Value>;
73
74    fn into_iter(self) -> Self::IntoIter {
75        self.iter()
76    }
77}
78
79impl<'a> IntoIterator for &'a mut ValueRecord {
80    type Item = &'a mut Value;
81    type IntoIter = std::slice::IterMut<'a, Value>;
82
83    fn into_iter(self) -> Self::IntoIter {
84        self.iter_mut()
85    }
86}
87
88// This implementation delegates the PartialEq implementation to the [Value]
89// (slice) implementation of PartialEq
90impl PartialEq for ValueRecord {
91    fn eq(&self, other: &Self) -> bool {
92        **self == **other
93    }
94}
95
96// had to impl hash for value record because conflicting implementations of hash trait
97impl Hash for ValueRecord {
98    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
99        (**self).hash(state);
100    }
101}
102
103macro_rules! impl_value_eq_tuple {
104    ( $len:literal; $(($T:ident, $idx:tt)),+ ) => {
105        impl<$($T),+> PartialEq<($($T,)+)> for Value
106        where
107            $(Value: PartialEq<$T>,)+
108        {
109            fn eq(&self, other: &($($T,)+)) -> bool {
110                match self {
111                    Value::Record(v) => {
112                        v.fields.len() == $len
113                            $(&& v.fields[$idx].eq(&other.$idx))+
114                    }
115                    _ => false,
116                }
117            }
118        }
119
120        impl<$($T),+> PartialEq<Value> for ($($T,)+)
121        where
122            $($T: PartialEq<Value>,)+
123        {
124            fn eq(&self, other: &Value) -> bool {
125                match other {
126                    Value::Record(v) => {
127                        v.fields.len() == $len
128                            $(&& self.$idx.eq(&v.fields[$idx]))+
129                    }
130                    _ => false,
131                }
132            }
133        }
134    };
135}
136
137impl_value_eq_tuple!(1; (T0, 0));
138impl_value_eq_tuple!(2; (T0, 0), (T1, 1));
139impl_value_eq_tuple!(3; (T0, 0), (T1, 1), (T2, 2));
140impl_value_eq_tuple!(4; (T0, 0), (T1, 1), (T2, 2), (T3, 3));
141impl_value_eq_tuple!(5; (T0, 0), (T1, 1), (T2, 2), (T3, 3), (T4, 4));
142impl_value_eq_tuple!(6; (T0, 0), (T1, 1), (T2, 2), (T3, 3), (T4, 4), (T5, 5));
143impl_value_eq_tuple!(7; (T0, 0), (T1, 1), (T2, 2), (T3, 3), (T4, 4), (T5, 5), (T6, 6));
144impl_value_eq_tuple!(8; (T0, 0), (T1, 1), (T2, 2), (T3, 3), (T4, 4), (T5, 5), (T6, 6), (T7, 7));
145impl_value_eq_tuple!(9; (T0, 0), (T1, 1), (T2, 2), (T3, 3), (T4, 4), (T5, 5), (T6, 6), (T7, 7), (T8, 8));
146impl_value_eq_tuple!(10; (T0, 0), (T1, 1), (T2, 2), (T3, 3), (T4, 4), (T5, 5), (T6, 6), (T7, 7), (T8, 8), (T9, 9));
147impl_value_eq_tuple!(11; (T0, 0), (T1, 1), (T2, 2), (T3, 3), (T4, 4), (T5, 5), (T6, 6), (T7, 7), (T8, 8), (T9, 9), (T10, 10));
148impl_value_eq_tuple!(12; (T0, 0), (T1, 1), (T2, 2), (T3, 3), (T4, 4), (T5, 5), (T6, 6), (T7, 7), (T8, 8), (T9, 9), (T10, 10), (T11, 11));