use std::collections::VecDeque;
use crate::{value::FromValue, Column, Error, Result, Value};
pub struct Rows {
columns: Vec<Column>,
rows: VecDeque<Row>,
}
impl Rows {
pub fn new(columns: Vec<Column>, rows: Vec<Row>) -> Self {
Self {
columns,
rows: rows.into(),
}
}
pub async fn next(&mut self) -> Result<Option<Row>> {
Ok(self.rows.pop_front())
}
pub fn column_count(&self) -> usize {
self.columns.len()
}
pub fn column_name(&self, idx: usize) -> Result<String> {
self.columns
.get(idx)
.map(|c| c.name().to_string())
.ok_or_else(|| {
Error::Misuse(format!(
"column index {idx} out of bounds (result has {} columns)",
self.columns.len()
))
})
}
pub fn column_names(&self) -> Vec<String> {
self.columns.iter().map(|c| c.name().to_string()).collect()
}
pub fn column_index(&self, name: &str) -> Result<usize> {
self.columns
.iter()
.position(|c| c.name().eq_ignore_ascii_case(name))
.ok_or_else(|| Error::Misuse(format!("column '{name}' not found in result set")))
}
pub fn columns(&self) -> Vec<Column> {
self.columns.clone()
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct Row {
values: Vec<Value>,
}
impl Row {
pub fn new(values: Vec<Value>) -> Self {
Self { values }
}
pub fn get_value(&self, idx: usize) -> Result<Value> {
self.values.get(idx).cloned().ok_or_else(|| {
Error::Misuse(format!(
"column index {idx} out of bounds (row has {} columns)",
self.values.len()
))
})
}
pub fn get<T: FromValue>(&self, idx: usize) -> Result<T> {
T::from_value(self.get_value(idx)?)
}
pub fn column_count(&self) -> usize {
self.values.len()
}
}