use super::cellvalue::{CellValue, CellValueToVal};
use super::error::{Error, ValueError};
use std::collections::VecDeque;
use std::result::Result;
pub struct QueryResult {
rows: VecDeque<Vec<CellValue>>,
rows_affected: usize,
}
impl QueryResult {
pub(crate) fn new(rows: VecDeque<Vec<CellValue>>, rows_affected: usize) -> QueryResult {
QueryResult {
rows,
rows_affected,
}
}
pub fn mapped<F, B>(self, f: F) -> MappedRows<F>
where
F: FnMut(&Row) -> Result<B, Error>,
{
MappedRows {
result: self,
map: f,
}
}
}
impl Iterator for QueryResult {
type Item = Row;
fn next(&mut self) -> Option<Row> {
match self.rows.pop_front() {
Some(row) => Some(Row { row: row }),
None => None,
}
}
}
pub struct Row {
row: Vec<CellValue>,
}
impl Row {
pub fn get<T>(&self, idx: usize) -> Result<T, Error>
where
CellValue: CellValueToVal<T>,
{
if let Some(cell_value) = self.row.get(idx) {
cell_value.clone().to_val()
} else {
Err(Error::ValueError(ValueError::new(
"This index doesn't exists",
)))
}
}
}
pub struct MappedRows<F> {
result: QueryResult,
map: F,
}
impl<T, F> Iterator for MappedRows<F>
where
F: FnMut(&Row) -> Result<T, Error>,
{
type Item = Result<T, Error>;
fn next(&mut self) -> Option<Result<T, Error>> {
let map = &mut self.map;
let row = self.result.next();
match row {
Some(r) => Some(map(&r)),
None => None,
}
}
}