use crate::{Error, SqlDataType, SqlDataTypeKind};
use std::{cmp, iter::FromIterator, marker::PhantomData};
pub trait ExtFnValueCursor {
type Item: ?Sized;
fn advance(&mut self) -> Result<(), Error>;
fn get(&self) -> Option<&Self::Item>;
fn is_null(&self) -> bool;
fn kind(&self) -> SqlDataTypeKind;
fn data_type(&self) -> SqlDataType;
fn len(&self) -> usize;
fn next(&mut self) -> Result<Option<&Self::Item>, Error> {
self.advance()?;
Ok((*self).get())
}
fn for_each<F>(mut self, mut f: F) -> Result<(), Error>
where
Self: Sized,
F: FnMut(&Self::Item),
{
while let Some(value) = self.next()? {
f(value);
}
Ok(())
}
fn fold<F, U>(mut self, init: U, f: F) -> Result<U, Error>
where
Self: Sized,
F: FnMut(U, &Self::Item) -> U,
{
let mut f = f;
let mut output = init;
while let Some(value) = self.next()? {
output = f(output, value);
}
Ok(output)
}
fn collect<U>(mut self) -> Result<U, Error>
where
Self: Sized,
U: for<'s> Extend<&'s Self::Item> + Default,
{
self.fold(U::default(), |mut out, x| {
out.extend(std::iter::once(x));
out
})
}
}
impl<'a, I: ?Sized> ExtFnValueCursor for &'a mut I
where
I: ExtFnValueCursor,
{
type Item = I::Item;
fn advance(&mut self) -> Result<(), Error> {
(**self).advance()
}
fn get(&self) -> Option<&I::Item> {
(**self).get()
}
fn next(&mut self) -> Result<Option<&I::Item>, Error> {
(**self).next()
}
fn is_null(&self) -> bool {
(**self).is_null()
}
fn kind(&self) -> SqlDataTypeKind {
(**self).kind()
}
fn data_type(&self) -> SqlDataType {
(**self).data_type()
}
fn len(&self) -> usize {
(**self).len()
}
}
#[cfg(test)]
mod test {
use super::*;
fn _is_object_safe(_: &dyn ExtFnValueCursor<Item = ()>) {}
}