use crate::{
data::Position,
io::{DataBaseError, SerdeError},
};
use super::{
block::{Block, BlockError, ChainedInstance, UnchainedInstance},
record::Record,
};
#[derive(Debug, Clone, Copy)]
pub enum ChainError {
SerdeError(SerdeError),
DataBaseError(DataBaseError),
AbsentValue,
Unspecified,
}
impl From<BlockError> for ChainError {
fn from(value: BlockError) -> Self {
match value {
BlockError::SerdeError(v) => ChainError::SerdeError(v),
BlockError::DataBaseError(u) => ChainError::DataBaseError(u),
BlockError::Unspecified => ChainError::Unspecified,
BlockError::NotValid(_) => unimplemented!(),
}
}
}
pub trait Chain: Sized {
type RecordType: Record;
type ChainedInstanceType: ChainedInstance<Self>;
type BlockType: Block<RecordType = Self::RecordType>;
fn append(
&mut self,
block: &UnchainedInstance<Self::RecordType>,
) -> Result<Self::ChainedInstanceType, ChainError>;
fn block_at(&self, pos: Position) -> Result<Self::BlockType, ChainError>;
fn get(&self, b: Self::ChainedInstanceType) -> Result<Self::BlockType, ChainError> {
let res = b.block(self)?;
Ok(res)
}
fn len(&self) -> Result<u64, ChainError>;
fn last_block(&self) -> Result<Option<Self::BlockType>, ChainError> {
let last = match self.len()? {
0 => return Ok(None),
v => v.into(),
};
self.block_at(last).map(|value| Some(value))
}
}