use super::ValueRef;
use crate::{ffi, sqlite3_match_version, sqlite3_require_version, types::*, FallibleIteratorMut};
use std::ptr;
pub struct ValueList<'list> {
#[cfg_attr(not(modern_sqlite), allow(unused))]
base: &'list mut ValueRef,
#[cfg_attr(not(modern_sqlite), allow(unused))]
pending: Option<Option<ptr::NonNull<ffi::sqlite3_value>>>,
}
impl<'list> ValueList<'list> {
pub fn from_value_ref(base: &'list mut ValueRef) -> Result<Self> {
let _ = base;
sqlite3_require_version!(3_038_000, unsafe {
let mut first: *mut ffi::sqlite3_value = ptr::null_mut();
Error::from_sqlite(ffi::sqlite3_vtab_in_first(base.as_ptr(), &mut first as _))?;
Ok(Self {
base,
pending: Some(ptr::NonNull::new(first)),
})
})
}
}
impl FallibleIteratorMut for ValueList<'_> {
type Item = ValueRef;
type Error = Error;
fn next(&mut self) -> Result<Option<&mut Self::Item>> {
sqlite3_match_version! {
3_038_000 => match self.pending.take() {
Some(Some(x)) => Ok(Some(unsafe { ValueRef::from_ptr(x.as_ptr()) })),
Some(None) => Ok(None),
None => {
let mut ret: *mut ffi::sqlite3_value = ptr::null_mut();
unsafe {
Error::from_sqlite(ffi::sqlite3_vtab_in_next(
self.base.as_ptr(),
&mut ret as _,
))?;
if ret.is_null() {
Ok(None)
} else {
Ok(Some(ValueRef::from_ptr(ret)))
}
}
}
},
_ => unreachable!(),
}
}
}