clia_rustorm_dao/
rows.rs

1use crate::{
2    Dao,
3    Value,
4};
5use serde_derive::{
6    Deserialize,
7    Serialize,
8};
9use std::slice;
10
11/// use this to store data retrieved from the database
12/// This is also slimmer than Vec<Dao> when serialized
13#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
14pub struct Rows {
15    pub columns: Vec<String>,
16    pub data: Vec<Vec<Value>>,
17    /// can be optionally set, indicates how many total rows are there in the table
18    pub count: Option<usize>,
19}
20
21impl Rows {
22    pub fn empty() -> Self { Rows::new(vec![]) }
23
24    pub fn new(columns: Vec<String>) -> Self {
25        Rows {
26            columns,
27            data: vec![],
28            count: None,
29        }
30    }
31
32    pub fn push(&mut self, row: Vec<Value>) { self.data.push(row) }
33
34    /// Returns an iterator over the `Row`s.
35    pub fn iter(&self) -> Iter {
36        Iter {
37            columns: self.columns.clone(),
38            iter: self.data.iter(),
39        }
40    }
41}
42
43/// An iterator over `Row`s.
44pub struct Iter<'a> {
45    columns: Vec<String>,
46    iter: slice::Iter<'a, Vec<Value>>,
47}
48
49impl<'a> Iterator for Iter<'a> {
50    type Item = Dao;
51
52    fn next(&mut self) -> Option<Dao> {
53        let next_row = self.iter.next();
54        if let Some(row) = next_row {
55            if !row.is_empty() {
56                let mut dao = Dao::new();
57                for (i, column) in self.columns.iter().enumerate() {
58                    if let Some(value) = row.get(i) {
59                        dao.insert_value(column, value);
60                    }
61                }
62                Some(dao)
63            } else {
64                None
65            }
66        } else {
67            None
68        }
69    }
70
71    fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
72}
73
74impl<'a> ExactSizeIterator for Iter<'a> {}
75
76#[cfg(test)]
77mod test {
78    use super::*;
79
80    #[test]
81    fn iteration_count() {
82        let columns = vec!["id".to_string(), "username".to_string()];
83        let data: Vec<Vec<Value>> = vec![vec![1.into(), "ivanceras".into()]];
84        let rows = Rows {
85            columns,
86            data,
87            count: None,
88        };
89        assert_eq!(1, rows.iter().count());
90    }
91
92    #[test]
93    fn iteration_count2() {
94        let columns = vec!["id".to_string(), "username".to_string()];
95        let data: Vec<Vec<Value>> = vec![vec![1.into(), "ivanceras".into()], vec![
96            2.into(),
97            "lee".into(),
98        ]];
99        let rows = Rows {
100            columns,
101            data,
102            count: None,
103        };
104        assert_eq!(2, rows.iter().count());
105    }
106
107    #[test]
108    fn dao() {
109        let columns = vec!["id".to_string(), "username".to_string()];
110        let data: Vec<Vec<Value>> = vec![vec![1.into(), "ivanceras".into()]];
111        let rows = Rows {
112            columns,
113            data,
114            count: None,
115        };
116        let mut dao = Dao::new();
117        dao.insert("id", 1);
118        dao.insert("username", "ivanceras");
119        assert_eq!(dao, rows.iter().next().unwrap());
120    }
121
122    #[test]
123    fn dao2() {
124        let columns = vec!["id".to_string(), "username".to_string()];
125        let data: Vec<Vec<Value>> = vec![vec![1.into(), "ivanceras".into()], vec![
126            2.into(),
127            "lee".into(),
128        ]];
129        let rows = Rows {
130            columns,
131            data,
132            count: None,
133        };
134        let mut iter = rows.iter();
135        let mut dao = Dao::new();
136        dao.insert("id", 1);
137        dao.insert("username", "ivanceras");
138        assert_eq!(dao, iter.next().unwrap());
139
140        let mut dao2 = Dao::new();
141        dao2.insert("id", 2);
142        dao2.insert("username", "lee");
143        assert_eq!(dao2, iter.next().unwrap());
144    }
145}