use super::{DecodeError, Decoder};
use crate::function::Selector;
pub trait DecodeContext: Sized {
type Context: ?Sized;
fn is_dynamic_context(context: &Self::Context) -> bool;
fn decode_context(decoder: &mut Decoder, context: &Self::Context) -> Result<Self, DecodeError>;
}
pub fn decode<T>(bytes: &[u8], context: &T::Context) -> Result<T, DecodeError>
where
T: DecodeContext,
{
let mut decoder = Decoder::new(bytes);
T::decode_context(&mut decoder, context)
}
pub fn decode_with_selector<T>(
selector: Selector,
bytes: &[u8],
context: &T::Context,
) -> Result<T, DecodeError>
where
T: DecodeContext,
{
decode_with_prefix(selector.as_ref(), bytes, context)
}
pub fn decode_with_prefix<T>(
prefix: &[u8],
bytes: &[u8],
context: &T::Context,
) -> Result<T, DecodeError>
where
T: DecodeContext,
{
let data = bytes.strip_prefix(prefix).ok_or(DecodeError::InvalidData)?;
decode(data, context)
}
impl<'a> Decoder<'a> {
pub fn read_context<T>(&mut self, context: &T::Context) -> Result<T, DecodeError>
where
T: DecodeContext,
{
if T::is_dynamic_context(context) {
T::decode_context(&mut self.slice()?, context)
} else {
T::decode_context(self, context)
}
}
}