use crate::{
base::{database::Column, scalar::Scalar},
sql::proof::ProvableResultElement,
};
pub trait ProvableResultColumn {
fn num_bytes(&self, length: u64) -> usize;
fn write(&self, out: &mut [u8], length: u64) -> usize;
}
impl<'a, T: ProvableResultElement<'a>> ProvableResultColumn for &[T] {
fn num_bytes(&self, length: u64) -> usize {
assert_eq!(self.len() as u64, length);
self.iter().map(ProvableResultElement::required_bytes).sum()
}
fn write(&self, out: &mut [u8], length: u64) -> usize {
let mut res = 0;
for i in 0..length {
let index: usize = usize::try_from(i).expect("Index out of bounds");
res += self[index].encode(&mut out[res..]);
}
res
}
}
impl<S: Scalar> ProvableResultColumn for Column<'_, S> {
fn num_bytes(&self, length: u64) -> usize {
match self {
Column::Boolean(col) => col.num_bytes(length),
Column::Uint8(col) => col.num_bytes(length),
Column::TinyInt(col) => col.num_bytes(length),
Column::SmallInt(col) => col.num_bytes(length),
Column::Int(col) => col.num_bytes(length),
Column::BigInt(col) | Column::TimestampTZ(_, _, col) => col.num_bytes(length),
Column::Int128(col) => col.num_bytes(length),
Column::Decimal75(_, _, col) | Column::Scalar(col) => col.num_bytes(length),
Column::VarChar((col, _)) => col.num_bytes(length),
Column::VarBinary((col, _)) => col.num_bytes(length),
}
}
fn write(&self, out: &mut [u8], length: u64) -> usize {
match self {
Column::Boolean(col) => col.write(out, length),
Column::Uint8(col) => col.write(out, length),
Column::TinyInt(col) => col.write(out, length),
Column::SmallInt(col) => col.write(out, length),
Column::Int(col) => col.write(out, length),
Column::BigInt(col) | Column::TimestampTZ(_, _, col) => col.write(out, length),
Column::Int128(col) => col.write(out, length),
Column::Decimal75(_, _, col) | Column::Scalar(col) => col.write(out, length),
Column::VarChar((col, _)) => col.write(out, length),
Column::VarBinary((col, _)) => col.write(out, length),
}
}
}
impl<'a, T: ProvableResultElement<'a>, const N: usize> ProvableResultColumn for [T; N] {
fn num_bytes(&self, length: u64) -> usize {
(&self[..]).num_bytes(length)
}
fn write(&self, out: &mut [u8], length: u64) -> usize {
(&self[..]).write(out, length)
}
}