use crate::error::{DecodeError, EncodeError};
use alloc::alloc::Global;
use auto_impl::auto_impl;
use core::{alloc::Allocator, ops::RangeBounds};
mod proof;
pub use proof::{Proof, Version, VersionedProof};
mod imp;
#[cfg(feature = "std")]
pub use imp::{Reader, Writer};
pub mod v1;
pub const MAGIC: &[u8; 31] = b"\x00OpenTimestamps\x00\x00Proof\x00\xbf\x89\xe2\xe8\x84\xe8\x92\x94";
pub trait Encoder: Sized {
fn encode_byte(&mut self, byte: u8) -> Result<(), EncodeError>;
fn encode_bytes(&mut self, bytes: impl AsRef<[u8]>) -> Result<(), EncodeError> {
let bytes = bytes.as_ref();
self.encode(bytes.len())?;
self.write_all(bytes)?;
Ok(())
}
fn encode_magic(&mut self) -> Result<(), EncodeError> {
self.write_all(&MAGIC[..])
}
fn encode(&mut self, value: impl Encode) -> Result<(), EncodeError> {
value.encode(self)
}
fn write_all(&mut self, buf: impl AsRef<[u8]>) -> Result<(), EncodeError>;
}
pub trait Decoder: Sized {
fn decode_byte(&mut self) -> Result<u8, DecodeError>;
fn decode_ranged<T: Decode + PartialOrd>(
&mut self,
range: impl RangeBounds<T>,
) -> Result<T, DecodeError> {
let val: T = self.decode()?;
if range.contains(&val) {
Ok(val)
} else {
Err(DecodeError::OutOfRange)
}
}
fn assert_magic(&mut self) -> Result<(), DecodeError> {
let mut buf = [0u8; MAGIC.len()];
self.read_exact(&mut buf)?;
if buf == *MAGIC {
Ok(())
} else {
Err(DecodeError::BadMagic)
}
}
fn decode<T: Decode>(&mut self) -> Result<T, DecodeError> {
T::decode(self)
}
fn decode_trailing<T: Decode>(&mut self) -> Result<Option<T>, DecodeError> {
T::decode_trailing(self)
}
fn decode_in<T: DecodeIn<A>, A: Allocator>(&mut self, alloc: A) -> Result<T, DecodeError> {
T::decode_in(self, alloc)
}
fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), DecodeError>;
}
#[auto_impl(&, &mut, Box, Rc, Arc)]
pub trait Encode {
fn encode(&self, writer: &mut impl Encoder) -> Result<(), EncodeError>;
}
pub trait Decode: Sized {
fn decode(decoder: &mut impl Decoder) -> Result<Self, DecodeError>;
fn decode_trailing(decoder: &mut impl Decoder) -> Result<Option<Self>, DecodeError> {
match Self::decode(decoder) {
Ok(value) => Ok(Some(value)),
Err(DecodeError::UnexpectedEof) => Ok(None),
Err(e) => Err(e),
}
}
}
pub trait DecodeIn<A: Allocator>: Sized {
fn decode_in(decoder: &mut impl Decoder, alloc: A) -> Result<Self, DecodeError>;
fn decode_trailing(decoder: &mut impl Decoder, alloc: A) -> Result<Option<Self>, DecodeError> {
match Self::decode_in(decoder, alloc) {
Ok(value) => Ok(Some(value)),
Err(DecodeError::UnexpectedEof) => Ok(None),
Err(e) => Err(e),
}
}
}
impl<T: DecodeIn<Global>> Decode for T {
fn decode(decoder: &mut impl Decoder) -> Result<Self, DecodeError> {
T::decode_in(decoder, Global)
}
fn decode_trailing(decoder: &mut impl Decoder) -> Result<Option<Self>, DecodeError> {
match Self::decode_in(decoder, Global) {
Ok(value) => Ok(Some(value)),
Err(DecodeError::UnexpectedEof) => Ok(None),
Err(e) => Err(e),
}
}
}