use crate::{
error::{DecodeError, EncodeError},
read::{Reader, Verifier},
sink::Sink,
wire::Wire,
};
use bytes::{Bytes, BytesMut};
use std::fmt;
pub trait Encode {
fn encoded_len(&self) -> usize;
fn encode<S: Sink>(&self, out: &mut S);
fn encode_to_vec(&self) -> Vec<u8> {
let mut out = Vec::with_capacity(self.encoded_len());
self.encode(&mut out);
out
}
fn encode_to_bytes(&self) -> Bytes {
let mut out = BytesMut::with_capacity(self.encoded_len());
self.encode(&mut out);
out.freeze()
}
fn encode_to_slice(&self, out: &mut [u8]) -> Result<usize, EncodeError> {
let needed = self.encoded_len();
if needed > out.len() {
return Err(EncodeError::BufferTooSmall {
needed,
available: out.len(),
});
}
let mut cursor = &mut out[..needed];
self.encode(&mut cursor);
Ok(needed)
}
}
pub trait Message: Encode + Sized {
type Wire: Wire<Owned = Self>;
fn view(bytes: Bytes) -> Result<View<Self::Wire>, DecodeError> {
View::new(bytes)
}
fn decode(bytes: Bytes) -> Result<Self, DecodeError> {
decode::<Self::Wire>(&bytes)
}
fn detach(&self) -> Self
where
Self: Clone,
{
Self::decode(self.encode_to_bytes()).unwrap_or_else(|_| self.clone())
}
}
pub fn verify<W: Wire>(bytes: &Bytes) -> Result<W::Ref<'_>, DecodeError> {
let mut verifier = Verifier::new(bytes)?;
let value = W::verify(&mut verifier)?;
verifier.finish()?;
Ok(value)
}
pub fn decode<W: Wire>(bytes: &Bytes) -> Result<W::Owned, DecodeError> {
let mut verifier = Verifier::new(bytes)?;
let value = W::verify_owned(&mut verifier)?;
verifier.finish()?;
Ok(value)
}
pub fn decode_with<T>(
bytes: &Bytes,
read: impl FnOnce(&mut Verifier<'_>) -> Result<T, DecodeError>,
) -> Result<T, DecodeError> {
let mut verifier = Verifier::new(bytes)?;
let value = read(&mut verifier)?;
verifier.finish()?;
Ok(value)
}
pub struct View<W: Wire> {
bytes: Bytes,
root: W::Root,
}
impl<W: Wire> View<W> {
pub fn new(bytes: Bytes) -> Result<Self, DecodeError> {
let root = W::root(&verify::<W>(&bytes)?);
Ok(View { bytes, root })
}
pub fn get(&self) -> W::Ref<'_> {
W::from_root(Reader::new(&self.bytes), self.root)
}
pub fn to_owned(&self) -> W::Owned {
W::read_owned(&mut Reader::new(&self.bytes))
}
pub fn as_bytes(&self) -> &Bytes {
&self.bytes
}
pub fn into_bytes(self) -> Bytes {
self.bytes
}
}
impl<W: Wire> Clone for View<W> {
fn clone(&self) -> Self {
View {
bytes: self.bytes.clone(),
root: self.root,
}
}
}
impl<W: Wire> fmt::Debug for View<W>
where
for<'a> W::Ref<'a>: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.get(), f)
}
}
impl<W: Wire> PartialEq for View<W> {
fn eq(&self, other: &Self) -> bool {
self.bytes == other.bytes
}
}
impl<W: Wire> Encode for View<W> {
fn encoded_len(&self) -> usize {
self.bytes.len()
}
fn encode<S: Sink>(&self, out: &mut S) {
out.put_data(&self.bytes);
}
}
impl Encode for () {
fn encoded_len(&self) -> usize {
0
}
fn encode<S: Sink>(&self, _out: &mut S) {}
}
impl Message for () {
type Wire = crate::wire::Void;
}