use traitful::seal;
use crate::{
class::UInt,
error::EndError,
result::{EndResult, FullResult},
Purge, Writer,
};
#[seal(Writer<'_>, Purge)]
pub trait Write {
fn remaining(&self) -> Option<usize>;
fn take(&mut self, len: usize) -> FullResult<Self>
where
Self: Sized;
fn bytes(&mut self, bytes: impl AsRef<[u8]>) -> FullResult;
fn str(&mut self, string: impl AsRef<str>) -> FullResult {
self.bytes(string.as_ref().as_bytes())
}
fn u8(&mut self, byte: u8) -> FullResult {
self.bytes([byte])
}
fn i8(&mut self, byte: i8) -> FullResult {
let [byte] = byte.to_ne_bytes();
self.u8(byte)
}
fn uleb128<T: UInt>(&mut self, value: T) -> FullResult {
let mut remaining = value;
while {
let byte = remaining.little();
remaining >>= 7;
let more = remaining != T::ZERO;
self.u8(if more { byte | 0x80 } else { byte & !0x80 })?;
more
} {}
Ok(())
}
fn end(&self) -> EndResult {
(self.remaining() == Some(0))
.then_some(())
.ok_or(EndError::from_remaining(self.remaining().unwrap_or(0)))
}
}