use crate::{
codec::Encode,
database::{Database, Typed},
misc::{Lease, Wrapper},
};
pub trait RecordValues<D>
where
D: Database,
{
fn encode_values<'inner, 'outer, 'rem, A>(
&self,
aux: &mut A,
ew: &mut D::EncodeWrapper<'inner, 'outer, 'rem>,
prefix_cb: impl FnMut(&mut A, &mut D::EncodeWrapper<'inner, 'outer, 'rem>) -> usize,
suffix_cb: impl FnMut(&mut A, &mut D::EncodeWrapper<'inner, 'outer, 'rem>, bool, usize) -> usize,
) -> Result<usize, D::Error>
where
'inner: 'outer;
fn len(&self) -> usize;
fn walk(
&self,
cb: impl FnMut(bool, Option<D::Ty>) -> Result<(), D::Error>,
) -> Result<(), D::Error>;
}
impl<D, T> RecordValues<D> for &T
where
D: Database,
T: RecordValues<D>,
{
#[inline]
fn encode_values<'inner, 'outer, 'rem, A>(
&self,
aux: &mut A,
ew: &mut D::EncodeWrapper<'inner, 'outer, 'rem>,
prefix_cb: impl FnMut(&mut A, &mut D::EncodeWrapper<'inner, 'outer, 'rem>) -> usize,
suffix_cb: impl FnMut(&mut A, &mut D::EncodeWrapper<'inner, 'outer, 'rem>, bool, usize) -> usize,
) -> Result<usize, D::Error> {
(**self).encode_values(aux, ew, prefix_cb, suffix_cb)
}
#[inline]
fn len(&self) -> usize {
(**self).len()
}
#[inline]
fn walk(
&self,
cb: impl FnMut(bool, Option<D::Ty>) -> Result<(), D::Error>,
) -> Result<(), D::Error> {
(**self).walk(cb)
}
}
impl<D, T> RecordValues<D> for &mut T
where
D: Database,
T: RecordValues<D>,
{
#[inline]
fn encode_values<'inner, 'outer, 'rem, A>(
&self,
aux: &mut A,
ew: &mut D::EncodeWrapper<'inner, 'outer, 'rem>,
prefix_cb: impl FnMut(&mut A, &mut D::EncodeWrapper<'inner, 'outer, 'rem>) -> usize,
suffix_cb: impl FnMut(&mut A, &mut D::EncodeWrapper<'inner, 'outer, 'rem>, bool, usize) -> usize,
) -> Result<usize, D::Error> {
(**self).encode_values(aux, ew, prefix_cb, suffix_cb)
}
#[inline]
fn len(&self) -> usize {
(**self).len()
}
#[inline]
fn walk(
&self,
cb: impl FnMut(bool, Option<D::Ty>) -> Result<(), D::Error>,
) -> Result<(), D::Error> {
(**self).walk(cb)
}
}
impl<D, T> RecordValues<D> for &[T]
where
D: Database,
T: Encode<D> + Typed<D>,
{
#[inline]
fn encode_values<'inner, 'outer, 'rem, A>(
&self,
aux: &mut A,
ew: &mut D::EncodeWrapper<'inner, 'outer, 'rem>,
mut prefix_cb: impl FnMut(&mut A, &mut D::EncodeWrapper<'inner, 'outer, 'rem>) -> usize,
mut suffix_cb: impl FnMut(&mut A, &mut D::EncodeWrapper<'inner, 'outer, 'rem>, bool, usize) -> usize,
) -> Result<usize, D::Error> {
let mut n: usize = 0;
for elem in *self {
encode(aux, elem, ew, &mut n, &mut prefix_cb, &mut suffix_cb)?;
}
Ok(n)
}
#[inline]
fn len(&self) -> usize {
(*self).len()
}
#[inline]
fn walk(
&self,
mut cb: impl FnMut(bool, Option<D::Ty>) -> Result<(), D::Error>,
) -> Result<(), D::Error> {
for elem in *self {
cb(elem.is_null(), elem.runtime_ty())?;
}
Ok(())
}
}
impl<D, T> RecordValues<D> for &mut [T]
where
D: Database,
T: Encode<D> + Typed<D>,
{
#[inline]
fn encode_values<'inner, 'outer, 'rem, A>(
&self,
aux: &mut A,
ew: &mut D::EncodeWrapper<'inner, 'outer, 'rem>,
mut prefix_cb: impl FnMut(&mut A, &mut D::EncodeWrapper<'inner, 'outer, 'rem>) -> usize,
mut suffix_cb: impl FnMut(&mut A, &mut D::EncodeWrapper<'inner, 'outer, 'rem>, bool, usize) -> usize,
) -> Result<usize, D::Error> {
let mut n: usize = 0;
for elem in self.iter() {
encode(aux, elem, ew, &mut n, &mut prefix_cb, &mut suffix_cb)?;
}
Ok(n)
}
#[inline]
fn len(&self) -> usize {
(**self).len()
}
#[inline]
fn walk(
&self,
mut cb: impl FnMut(bool, Option<D::Ty>) -> Result<(), D::Error>,
) -> Result<(), D::Error> {
for elem in self.iter() {
cb(elem.is_null(), elem.runtime_ty())?;
}
Ok(())
}
}
impl<D, I, T> RecordValues<D> for Wrapper<I>
where
D: Database,
I: Clone + Iterator<Item = T>,
T: Encode<D> + Typed<D>,
{
#[inline]
fn encode_values<'inner, 'outer, 'rem, A>(
&self,
aux: &mut A,
ew: &mut D::EncodeWrapper<'inner, 'outer, 'rem>,
mut prefix_cb: impl FnMut(&mut A, &mut D::EncodeWrapper<'inner, 'outer, 'rem>) -> usize,
mut suffix_cb: impl FnMut(&mut A, &mut D::EncodeWrapper<'inner, 'outer, 'rem>, bool, usize) -> usize,
) -> Result<usize, D::Error> {
let mut n: usize = 0;
for elem in self.0.clone() {
encode(aux, &elem, ew, &mut n, &mut prefix_cb, &mut suffix_cb)?;
}
Ok(n)
}
#[inline]
fn len(&self) -> usize {
let (l, u) = self.0.size_hint();
u.unwrap_or(l)
}
#[inline]
fn walk(
&self,
mut cb: impl FnMut(bool, Option<D::Ty>) -> Result<(), D::Error>,
) -> Result<(), D::Error> {
for elem in self.0.clone() {
cb(elem.is_null(), elem.runtime_ty())?;
}
Ok(())
}
}
pub(crate) fn encode<'inner, 'outer, 'rem, A, D, T>(
aux: &mut A,
elem: &T,
ew: &mut D::EncodeWrapper<'inner, 'outer, 'rem>,
n: &mut usize,
prefix_cb: &mut impl FnMut(&mut A, &mut D::EncodeWrapper<'inner, 'outer, 'rem>) -> usize,
suffix_cb: &mut impl FnMut(&mut A, &mut D::EncodeWrapper<'inner, 'outer, 'rem>, bool, usize) -> usize,
) -> Result<(), D::Error>
where
D: Database,
T: Encode<D>,
{
*n = n.wrapping_add(prefix_cb(aux, ew));
let elem_before = ew.lease().len();
elem.encode(ew)?;
let elem_len = ew.lease().len().wrapping_sub(elem_before);
*n = n.wrapping_add(elem_len);
*n = n.wrapping_add(suffix_cb(aux, ew, elem.is_null(), elem_len));
Ok(())
}