1use std::fmt::Debug;
8use std::marker::PhantomData;
9use std::rc::Rc;
10
11use error::*;
12use field::Value;
13use frame::Framed;
14
15pub trait DataIndex: Debug {
17 type DType;
19
20 fn get_datum(&self, idx: usize) -> Result<Value<&Self::DType>>;
22
23 fn len(&self) -> usize;
25
26 fn is_empty(&self) -> bool {
28 self.len() == 0
29 }
30
31 fn iter(&self) -> DataIterator<Self::DType>
33 where
34 Self: Sized,
35 {
36 DataIterator::new(self)
37 }
38
39 fn permute(self, permutation: &[usize]) -> Framed<Self::DType, Self>
43 where
44 Self: Sized,
45 {
46 Framed::new(Rc::new(permutation.to_vec().into()), self)
47 }
48
49 fn to_vec(&self) -> Vec<Self::DType>
54 where
55 Self: Sized,
56 Self::DType: Clone,
57 {
58 self.iter()
59 .filter_map(|value| match value {
60 Value::Exists(value) => Some(value.clone()),
61 Value::Na => None,
62 })
63 .collect()
64 }
65
66 fn to_value_vec(&self) -> Vec<Value<Self::DType>>
68 where
69 Self: Sized,
70 Self::DType: Clone,
71 {
72 self.iter().map(|value| value.cloned()).collect()
73 }
74}
75pub trait DataIndexMut: DataIndex {
77 fn push(&mut self, value: Value<Self::DType>);
79
80 fn take_datum(&mut self, idx: usize) -> Result<Value<Self::DType>>
82 where
83 Self::DType: Default;
84
85 fn drain(&mut self) -> DrainIterator<Self::DType>
87 where
88 Self: Sized,
89 {
90 DrainIterator::new(self)
91 }
92}
93
94pub struct DataIterator<'a, T>
96where
97 T: 'a,
98{
99 data: &'a dyn DataIndex<DType = T>,
100 cur_idx: usize,
101 phantom: PhantomData<T>,
102}
103impl<'a, T> DataIterator<'a, T>
104where
105 T: 'a,
106{
107 pub fn new(data: &'a dyn DataIndex<DType = T>) -> DataIterator<'a, T> {
109 DataIterator {
110 data,
111 cur_idx: 0,
112 phantom: PhantomData,
113 }
114 }
115
116 pub fn map_existing<B, F>(self, f: F) -> ValueMap<'a, T, Self, F>
119 where
120 Self: Iterator<Item = Value<&'a T>>,
121 F: FnMut(&'a T) -> B,
122 {
123 ValueMap {
124 iter: self,
125 f,
126 _t: PhantomData,
127 }
128 }
129}
130
131impl<'a, T> Iterator for DataIterator<'a, T>
132where
133 T: 'a,
134{
135 type Item = Value<&'a T>;
136
137 fn next(&mut self) -> Option<Value<&'a T>> {
138 if self.cur_idx < self.data.len() {
139 let out = Some(self.data.get_datum(self.cur_idx).unwrap());
140 self.cur_idx += 1;
141 out
142 } else {
143 None
144 }
145 }
146}
147
148#[derive(Clone)]
152pub struct ValueMap<'a, T, I, F> {
153 iter: I,
154 f: F,
155 _t: PhantomData<&'a T>,
156}
157
158impl<'a, B, T, I, F> Iterator for ValueMap<'a, T, I, F>
159where
160 I: Iterator<Item = Value<&'a T>>,
161 F: FnMut(&'a T) -> B,
162{
163 type Item = Value<B>;
164
165 #[inline]
166 fn next(&mut self) -> Option<Value<B>> {
167 self.iter.next().map(|value| value.map(&mut self.f))
168 }
169}
170
171pub struct DrainIterator<'a, T>
173where
174 T: 'a,
175{
176 data: &'a mut dyn DataIndexMut<DType = T>,
177 cur_idx: usize,
178 phantom: PhantomData<T>,
179}
180
181impl<'a, T> DrainIterator<'a, T>
182where
183 T: 'a,
184{
185 pub fn new(data: &'a mut dyn DataIndexMut<DType = T>) -> DrainIterator<'a, T> {
187 DrainIterator {
188 data,
189 cur_idx: 0,
190 phantom: PhantomData,
191 }
192 }
193}
194
195impl<'a, T> Iterator for DrainIterator<'a, T>
196where
197 T: 'a + Default,
198{
199 type Item = Value<T>;
200
201 fn next(&mut self) -> Option<Value<T>> {
202 if self.cur_idx < self.data.len() {
203 let out = Some(self.data.take_datum(self.cur_idx).unwrap());
204 self.cur_idx += 1;
205 out
206 } else {
207 None
208 }
209 }
210}
211
212pub trait NRows {
214 fn nrows(&self) -> usize;
216}
217impl<DI> NRows for DI
218where
219 DI: DataIndex,
220{
221 fn nrows(&self) -> usize {
222 self.len()
223 }
224}
225
226#[cfg(test)]
227mod tests {
228 use super::*;
229
230 use field::FieldData;
231
232 #[test]
233 fn convert() {
234 let field_data = FieldData::from_field_vec(vec![
235 Value::Exists(2u64),
236 Value::Exists(5),
237 Value::Na,
238 Value::Exists(1),
239 Value::Exists(8),
240 ]);
241 let new_field_data = field_data
242 .iter()
243 .map_existing(|u| *u as i64)
244 .collect::<FieldData<i64>>();
245 assert_eq!(
246 new_field_data.to_value_vec(),
247 vec![
248 Value::Exists(2i64),
249 Value::Exists(5),
250 Value::Na,
251 Value::Exists(1),
252 Value::Exists(8),
253 ]
254 );
255 }
256}