pub mod primitives;
pub mod section;
use alloc::string::String;
use alloc::vec::Vec;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum DecodeError {
UnexpectedEof,
InvalidTag(u8),
InvalidUtf8,
Invalid(&'static str),
}
#[derive(Debug, Default, Clone)]
pub struct Encoder {
buf: Vec<u8>,
}
impl Encoder {
pub fn new() -> Self {
Encoder { buf: Vec::new() }
}
pub fn with_capacity(cap: usize) -> Self {
Encoder {
buf: Vec::with_capacity(cap),
}
}
pub fn write_bytes(&mut self, bytes: &[u8]) {
self.buf.extend_from_slice(bytes);
}
pub fn finish(self) -> Vec<u8> {
self.buf
}
pub fn len(&self) -> usize {
self.buf.len()
}
pub fn is_empty(&self) -> bool {
self.buf.is_empty()
}
}
#[derive(Debug, Clone)]
pub struct Decoder<'a> {
data: &'a [u8],
pos: usize,
}
impl<'a> Decoder<'a> {
pub fn new(data: &'a [u8]) -> Self {
Decoder { data, pos: 0 }
}
pub fn read_bytes(&mut self, n: usize) -> Result<&'a [u8], DecodeError> {
let end = self.pos.checked_add(n).ok_or(DecodeError::UnexpectedEof)?;
if end > self.data.len() {
return Err(DecodeError::UnexpectedEof);
}
let slice = &self.data[self.pos..end];
self.pos = end;
Ok(slice)
}
pub fn position(&self) -> usize {
self.pos
}
pub fn remaining(&self) -> usize {
self.data.len() - self.pos
}
}
pub trait Encode {
fn encode(&self, enc: &mut Encoder);
fn to_bytes(&self) -> Vec<u8> {
let mut enc = Encoder::new();
self.encode(&mut enc);
enc.finish()
}
}
pub trait Decode: Sized {
fn decode(dec: &mut Decoder<'_>) -> Result<Self, DecodeError>;
fn from_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
let mut dec = Decoder::new(bytes);
Self::decode(&mut dec)
}
}
pub(crate) fn utf8_from(bytes: &[u8]) -> Result<String, DecodeError> {
core::str::from_utf8(bytes)
.map(|s| s.into())
.map_err(|_| DecodeError::InvalidUtf8)
}