diff --git a/src/lib.rs b/src/lib.rs index ba52022..4b8f67b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,6 +17,7 @@ use std::{ struct Request; +#[derive(Clone)] enum Field { Static(String), } @@ -136,17 +137,52 @@ mod records { struct Response { data: HashMap>, + counter: usize, } impl Response { fn new() -> Self { Self { data: HashMap::new(), + counter: 0, } } - fn count(&self) -> usize { - 0 + fn add(&mut self, rec: Record) -> Result<(), String> { + if self.data.is_empty() { + for (key, value) in rec.iter() { + let mut store = Vec::new(); + store.push(value.clone()); + self.data.insert(key.to_string(), store); + } + } else { + for (key, value) in rec.iter() { + match self.data.get_mut(key) { + Some(data) => data.push(value.clone()), + None => return Err("bad".to_string()), + } + } + } + Ok(()) + } +} + +impl Iterator for Response { + type Item = Record; + + fn next(&mut self) -> Option { + if self.data.is_empty() { + return None; + } + let mut rec = Record::new(); + for (key, value) in self.data.iter() { + if self.counter >= value.len() { + return None; + } + rec.add(key, value[self.counter].clone()); + } + self.counter += 1; + Some(rec) } } @@ -156,9 +192,57 @@ mod responses { #[test] fn create_response() { - let res = Response::new(); + let mut res = Response::new(); assert!(res.data.is_empty()); - assert_eq!(res.count(), 0); + assert!(res.next().is_none()); + } + + #[test] + fn add_records() { + let mut res = Response::new(); + let columns = ["col1", "col2"]; + let count = 3; + let field_cnt = &count * columns.len(); + let mut fields = 0..field_cnt; + for _ in 0..count { + let mut rec = Record::new(); + for col in columns { + rec.add(col, fields.next().unwrap().to_string()); + } + res.add(rec); + } + fields = 0..field_cnt; + for _ in 0..count { + match res.next() { + Some(rec) => { + assert_eq!(rec.len(), columns.len()); + for col in columns { + match rec.get(col).unwrap() { + Field::Static(txt) => { + assert_eq!(txt.clone(), fields.next().unwrap().to_string()) + } + } + } + } + None => unreachable!("Should have returned data"), + } + } + assert!(res.next().is_none(), "exceeded the correct of records"); + } + + #[test] + fn number_of_columns_mismatch() { + let mut res = Response::new(); + let mut rec1 = Record::new(); + let mut rec2 = Record::new(); + rec1.add("one", "one"); + rec2.add("one", "one"); + rec2.add("two", "two"); + res.add(rec1).unwrap(); + match res.add(rec2) { + Ok(_) => unreachable!("Should not accept additional value"), + Err(_) => {} + } } }