use iris_abi::{CapabilitySet, Reader, Result as AbiResult, Writer};
use crate::digest::Digest;
use crate::layout::{DIGEST_SIZE, DecoderLocation, SchemaEncoding, SectionKind};
#[derive(Clone, PartialEq, Eq, Debug, serde::Serialize, serde::Deserialize)]
pub struct Dataset {
pub rows: u64,
pub name: String,
}
impl Dataset {
pub const VERSION: u16 = 1;
pub fn encode(&self, w: &mut Writer<'_>) -> AbiResult<()> {
w.u64(self.rows)?;
w.var_str(&self.name)
}
pub fn decode(p: &mut Reader<'_>) -> AbiResult<Self> {
Ok(Self {
rows: p.u64()?,
name: p.var_str()?.to_owned(),
})
}
}
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct Schema<'a> {
pub encoding: SchemaEncoding,
pub bytes: &'a [u8],
}
impl<'a> Schema<'a> {
pub const VERSION: u16 = 1;
pub fn encode(&self, w: &mut Writer<'_>) -> AbiResult<()> {
w.u32(self.encoding.code())?;
w.var_bytes(self.bytes)
}
pub fn decode(p: &mut Reader<'a>) -> AbiResult<Self> {
Ok(Self {
encoding: SchemaEncoding::from_code(p.u32()?),
bytes: p.var_bytes()?,
})
}
}
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct DecoderRef<'a> {
pub abi_major: u16,
pub abi_minor: u16,
pub location: DecoderLocation,
pub digest: Digest,
pub required: CapabilitySet,
pub name: &'a str,
}
impl<'a> DecoderRef<'a> {
pub const VERSION: u16 = 1;
pub fn encode(&self, w: &mut Writer<'_>) -> AbiResult<()> {
w.u16(self.abi_major)?;
w.u16(self.abi_minor)?;
let (kind, section) = match self.location {
DecoderLocation::Embedded { section } => (0, section),
DecoderLocation::External => (1, 0),
};
w.u32(kind)?;
w.u32(section)?;
w.u32(0)?;
w.raw(self.digest.as_bytes())?;
w.var_bytes(self.required.as_bytes())?;
w.var_str(self.name)
}
pub fn decode(p: &mut Reader<'a>) -> AbiResult<Self> {
let abi_major = p.u16()?;
let abi_minor = p.u16()?;
let kind = p.u32()?;
let section = p.u32()?;
let _reserved = p.u32()?;
let raw = p.bytes(DIGEST_SIZE)?;
let mut digest = [0u8; DIGEST_SIZE];
digest.copy_from_slice(raw);
Ok(Self {
abi_major,
abi_minor,
location: if kind == 0 {
DecoderLocation::Embedded { section }
} else {
DecoderLocation::External
},
digest: Digest(digest),
required: p.capability_set()?,
name: p.var_str()?,
})
}
}
#[derive(Clone, Copy, PartialEq, Eq, Debug, serde::Serialize, serde::Deserialize)]
pub struct Section {
pub id: u32,
pub kind: SectionKind,
pub offset: u64,
pub len: u64,
pub digest: Digest,
}
impl Section {
pub const VERSION: u16 = 1;
#[must_use]
pub const fn end(&self) -> Option<u64> {
self.offset.checked_add(self.len)
}
pub fn encode(&self, w: &mut Writer<'_>) -> AbiResult<()> {
w.u32(self.id)?;
w.u32(self.kind.code())?;
w.u64(self.offset)?;
w.u64(self.len)?;
w.raw(self.digest.as_bytes())
}
pub fn decode(p: &mut Reader<'_>) -> AbiResult<Self> {
let id = p.u32()?;
let kind = SectionKind::from_code(p.u32()?);
let offset = p.u64()?;
let len = p.u64()?;
let raw = p.bytes(DIGEST_SIZE)?;
let mut digest = [0u8; DIGEST_SIZE];
digest.copy_from_slice(raw);
Ok(Self {
id,
kind,
offset,
len,
digest: Digest(digest),
})
}
}