futures-codec2 0.1.0

Utilities for encoding and decoding frames forked from tokio-util.
Documentation
use crate::{Decoder, Encoder};

use bytes::{Buf, BufMut, BytesMut};
use serde::{Serialize, Deserialize};
use serde_cbor as cbor;
use std::marker::PhantomData;

/// A [`Decoder`] and [`Encoder`] implementation that (de)serializes CBOR.
#[derive(Debug)]
pub struct CborCodec<T> {
    _phantom: PhantomData<fn() -> T>,
}

impl<T> Default for CborCodec<T> {
    fn default() -> Self {
        Self {
            _phantom: PhantomData,
        }
    }
}

impl<T> Clone for CborCodec<T> {
    fn clone(&self) -> Self {
        Self {
            _phantom: PhantomData,
        }
    }
}

impl<T> Decoder for CborCodec<T>
where T: for<'de> Deserialize<'de> {
    type Item = T;
    type Error = cbor::Error;

    fn decode(&mut self, buf: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
        let (res, off) = {
            let mut iter = cbor::Deserializer::from_slice(&buf).into_iter();
            match iter.next() {
                Some(Ok(v)) => (Ok(Some(v)), iter.byte_offset()),
                Some(Err(e)) if e.is_eof() => (Ok(None), 0),
                Some(Err(e)) => (Err(e.into()), iter.byte_offset()),
                None => (Ok(None), iter.byte_offset()),
            }
        };
        buf.advance(off);
        res
    }
}

impl<I, T> Encoder<I> for CborCodec<T>
where I: Serialize {
    type Error = cbor::Error;

    fn encode(&mut self, item: I, buf: &mut BytesMut) -> Result<(), Self::Error> {
        cbor::to_writer(buf.writer(), &item)?;
        Ok(())
    }
}