flowly-core 0.6.0

Flowly is a library of modular and reusable components for building robust pipelines processing audio, video and other.
Documentation
use arrayvec::ArrayVec;
pub use bytes::TryGetError;
use bytes::{Buf, BufMut, Bytes, BytesMut};

pub trait Reader: Buf {
    fn read_string(&mut self, len: usize) -> Result<String, TryGetError> {
        let mut buf = BytesMut::with_capacity(len);
        buf.put(Buf::take(self, len));

        String::from_utf8(buf.into()).map_err(|_| TryGetError {
            requested: 0,
            available: 0,
        })
    }

    fn read_array<const N: usize>(&mut self, len: usize) -> Result<ArrayVec<u8, N>, TryGetError> {
        let mut arr = ArrayVec::new();
        unsafe { arr.set_len(usize::min(N, len)) };
        self.read_slice(&mut arr)?;

        Ok(arr)
    }

    fn read_slice(&mut self, dst: &mut [u8]) -> Result<(), TryGetError> {
        self.try_copy_to_slice(dst)
    }

    fn read_bytes(&mut self, len: usize) -> Result<Bytes, TryGetError> {
        let available = Self::remaining(self);
        if available < len {
            Err(TryGetError {
                requested: len,
                available,
            })
        } else {
            Ok(self.copy_to_bytes(len))
        }
    }

    fn read_bytes_prepend(&mut self, len: usize, prep: &[u8]) -> Result<Bytes, TryGetError> {
        let available = Self::remaining(self);

        if available < len {
            Err(TryGetError {
                requested: len,
                available,
            })
        } else {
            let mut ret = BytesMut::with_capacity(len + prep.len());
            ret.put(prep);
            ret.put(self.take(len));

            Ok(ret.freeze())
        }
    }

    #[inline]
    fn read_u8(&mut self) -> Result<u8, TryGetError> {
        self.try_get_u8()
    }

    #[inline]
    fn read_i8(&mut self) -> Result<i8, TryGetError> {
        self.try_get_i8()
    }

    #[inline]
    fn read_u16(&mut self) -> Result<u16, TryGetError> {
        self.try_get_u16()
    }

    #[inline]
    fn read_i16(&mut self) -> Result<i16, TryGetError> {
        self.try_get_i16()
    }

    #[inline]
    fn read_u32(&mut self) -> Result<u32, TryGetError> {
        self.try_get_u32()
    }

    #[inline]
    fn read_i32(&mut self) -> Result<i32, TryGetError> {
        self.try_get_i32()
    }

    #[inline]
    fn read_u64(&mut self) -> Result<u64, TryGetError> {
        self.try_get_u64()
    }

    #[inline]
    fn read_i64(&mut self) -> Result<i64, TryGetError> {
        self.try_get_i64()
    }

    #[inline]
    fn read_uint(&mut self, nbytes: usize) -> Result<u64, TryGetError> {
        self.try_get_uint(nbytes)
    }

    #[inline]
    fn read_int(&mut self, nbytes: usize) -> Result<i64, TryGetError> {
        self.try_get_int(nbytes)
    }

    #[inline]
    fn read_f32(&mut self) -> Result<f32, TryGetError> {
        self.try_get_f32()
    }

    #[inline]
    fn read_f64(&mut self) -> Result<f64, TryGetError> {
        self.try_get_f64()
    }

    #[inline]
    fn peek_u8(&mut self) -> Result<u8, TryGetError> {
        self.chunk().read_u8()
    }

    #[inline]
    fn read_i24(&mut self) -> Result<i32, TryGetError> {
        Ok(self.read_int(3)? as i32)
    }

    #[inline]
    fn read_u24(&mut self) -> Result<u32, TryGetError> {
        Ok(self.read_uint(3)? as u32)
    }

    #[inline]
    fn read_i48(&mut self) -> Result<i64, TryGetError> {
        self.read_int(6)
    }

    #[inline]
    fn read_u48(&mut self) -> Result<u64, TryGetError> {
        self.read_uint(6)
    }

    #[inline]
    fn read_remaining(&mut self) -> Bytes {
        self.read_bytes(self.remaining()).unwrap()
    }
}

impl<T: Buf> Reader for T {}

pub trait ReaderExt: Sized + Reader {
    #[inline]
    fn read_u8p2<const A: u8, const B: u8>(&mut self) -> Result<(u8, u8), TryGetError> {
        const {
            assert! {A as usize + B as usize == 8};
        }

        let val = self.read_u8()?;
        let mask = (((1u16 << A) - 1) << B) as u8;

        Ok((val >> B, val & (!mask)))
    }

    #[inline]
    fn read_u8p3<const A: u8, const B: u8, const C: u8>(
        &mut self,
    ) -> Result<(u8, u8, u8), TryGetError> {
        const {
            assert! {A as usize + B as usize + C as usize == 8};
        }

        let val = self.read_u8()?;
        let b_mask = ((1u16 << B) - 1) as u8;
        let c_mask = ((1u16 << C) - 1) as u8;

        Ok(((val >> (B + C)), (val >> C) & b_mask, val & c_mask))
    }

    #[inline]
    fn read_u8p4<const A: u8, const B: u8, const C: u8, const D: u8>(
        &mut self,
    ) -> Result<(u8, u8, u8, u8), TryGetError> {
        const {
            assert! {A as usize + B as usize + C as usize + D as usize == 8};
        }

        let val = self.read_u8()?;
        let b_mask = ((1u16 << B) - 1) as u8;
        let c_mask = ((1u16 << C) - 1) as u8;
        let d_mask = ((1u16 << D) - 1) as u8;

        Ok((
            (val >> (B + C + D)),
            (val >> (C + D)) & b_mask,
            (val >> D) & c_mask,
            val & d_mask,
        ))
    }

    #[inline]
    fn read_u16p2<const A: u8, const B: u8>(&mut self) -> Result<(u16, u16), TryGetError> {
        const {
            assert! {A as usize + B as usize == 16};
        }

        let val = self.read_u16()?;
        let mask = (((1u32 << A) - 1) << B) as u16;

        Ok((val >> B, val & (!mask)))
    }

    #[inline]
    fn read_u16p3<const A: u8, const B: u8, const C: u8>(
        &mut self,
    ) -> Result<(u16, u16, u16), TryGetError> {
        const {
            assert! {A as usize + B as usize + C as usize == 16};
        }

        let val = self.read_u16()?;
        let b_mask = ((1u32 << B) - 1) as u16;
        let c_mask = ((1u32 << C) - 1) as u16;

        Ok(((val >> (B + C)), (val >> C) & b_mask, val & c_mask))
    }

    #[inline]
    fn read_u16p4<const A: u16, const B: u16, const C: u16, const D: u16>(
        &mut self,
    ) -> Result<(u16, u16, u16, u16), TryGetError> {
        const {
            assert! {A as usize + B as usize + C as usize + D as usize == 16};
        }

        let val = self.read_u16()?;
        let b_mask = ((1u32 << B) - 1) as u16;
        let c_mask = ((1u32 << C) - 1) as u16;
        let d_mask = ((1u32 << D) - 1) as u16;

        Ok((
            (val >> (B + C + D)),
            (val >> (C + D)) & b_mask,
            (val >> D) & c_mask,
            val & d_mask,
        ))
    }
}

impl<T: Reader> ReaderExt for T {}

pub trait Writer: BufMut {
    #[inline]
    fn put_i24(&mut self, val: i32) {
        self.put_int(val as i64, 3)
    }

    #[inline]
    fn put_u24(&mut self, val: u32) {
        self.put_uint(val as u64, 3)
    }

    #[inline]
    fn put_i48(&mut self, val: i64) {
        self.put_int(val, 6)
    }

    #[inline]
    fn put_u48(&mut self, val: u64) {
        self.put_uint(val, 6)
    }

    #[inline]
    fn put_str(&mut self, string: &str) {
        self.put_slice(string.as_bytes())
    }
}

impl<T: BufMut> Writer for T {}

pub trait WriterExt: Writer {
    fn put_u8p2<const A: u8, const B: u8>(&mut self, a: u8, b: u8) {
        let _ = b;
        let _ = a;
        const {
            assert!(A + B == 8);
        }

        todo!()
    }

    fn put_u8p3<const A: u8, const B: u8, const C: u8>(&mut self, a: u8, b: u8, c: u8) {
        let _ = c;
        let _ = b;
        let _ = a;
        const {
            assert!(A + B + C == 8);
        }

        todo!()
    }

    fn put_u8p4<const A: u8, const B: u8, const C: u8, const D: u8>(
        &mut self,
        a: u8,
        b: u8,
        c: u8,
        d: u8,
    ) {
        let _ = d;
        let _ = c;
        let _ = b;
        let _ = a;
        const {
            assert!(A + B + C + D == 8);
        }

        todo!()
    }

    fn put_u16p2<const A: u8, const B: u8>(&mut self, a: u16, b: u16) {
        let _ = b;
        let _ = a;
        const {
            assert!(A + B == 16);
        }

        todo!()
    }

    fn put_u16p3<const A: u8, const B: u8, const C: u8>(&mut self, a: u16, b: u16, c: u16) {
        let _ = c;
        let _ = b;
        let _ = a;
        const {
            assert!(A + B + C == 16);
        }

        todo!()
    }

    fn put_u16p4<const A: u8, const B: u8, const C: u8, const D: u8>(
        &mut self,
        a: u16,
        b: u16,
        c: u16,
        d: u16,
    ) {
        let _ = d;
        let _ = c;
        let _ = b;
        let _ = a;
        const {
            assert!(A + B + C + D == 16);
        }

        todo!()
    }
}

impl<T: Writer> WriterExt for T {}

pub trait Decoder<T> {
    type Error;

    fn decode<R: Reader>(&mut self, reader: &mut R) -> Result<T, Self::Error>;
}

pub trait Encoder<T> {
    type Error;

    fn encode<W: Writer>(&mut self, item: &T, writer: &mut W) -> Result<(), Self::Error>;
    fn size_hint() -> (usize, Option<usize>) {
        (0, None)
    }
    fn estimate_size(&self, _: &T) -> usize {
        Self::size_hint().0
    }
}

#[derive(Debug, Default, Clone, Copy)]
pub struct BytesDecoder;

impl Decoder<Bytes> for BytesDecoder {
    type Error = crate::Void;

    fn decode<R: Reader>(&mut self, reader: &mut R) -> Result<Bytes, Self::Error> {
        Ok(reader.read_bytes(reader.remaining()).unwrap())
    }
}