use crate::builtins::{Lazy, UnparsedBytes, WasmbinCountable};
use crate::io::{Decode, DecodeError, DecodeErrorKind, Encode};
use crate::visit::Visit;
impl Encode for [u8] {
fn encode(&self, w: &mut impl std::io::Write) -> std::io::Result<()> {
self.len().encode(w)?;
w.write_all(self)
}
}
impl Decode for Vec<u8> {
fn decode(r: &mut impl std::io::Read) -> Result<Self, DecodeError> {
let size = u32::decode(r)?;
let mut taken = std::io::Read::take(r, size.into());
let bytes = UnparsedBytes::decode(&mut taken)?.bytes;
if taken.limit() != 0 {
return Err(DecodeErrorKind::UnrecognizedData.into());
}
Ok(bytes)
}
}
#[derive(Default, PartialEq, Eq, Hash, Clone, Visit)]
pub struct Blob<T: Decode> {
pub contents: Lazy<T>,
}
impl<T: Decode> std::ops::Deref for Blob<T> {
type Target = Lazy<T>;
fn deref(&self) -> &Self::Target {
&self.contents
}
}
impl<T: Decode> std::ops::DerefMut for Blob<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.contents
}
}
impl<T: Decode + std::fmt::Debug> std::fmt::Debug for Blob<T> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
self.contents.fmt(f)
}
}
impl<T: Decode + Encode> Encode for Blob<T> {
fn encode(&self, w: &mut impl std::io::Write) -> std::io::Result<()> {
let mut buf;
let raw: &[u8] = match self.contents.try_as_raw() {
Ok(raw) => raw,
Err(value) => {
buf = <Vec<u8>>::new();
value.encode(&mut buf)?;
&buf
}
};
raw.encode(w)
}
}
impl<T: Decode> Decode for Blob<T> {
fn decode(r: &mut impl std::io::Read) -> Result<Self, DecodeError> {
let raw = <Vec<u8>>::decode(r)?;
Ok(Self {
contents: Lazy::from_raw(UnparsedBytes { bytes: raw }),
})
}
}
impl<T: Decode + WasmbinCountable> WasmbinCountable for Blob<T> {}
impl<T: Decode> From<T> for Blob<T> {
fn from(value: T) -> Self {
Blob {
contents: value.into(),
}
}
}