async-mp4 0.1.1

Async Mp4 Muxer and Demuxer in pure rust
Documentation
use std::fmt::{Debug, Formatter};
use num_traits::AsPrimitive;
use crate::bytes_read::{Mp4Readable, ReadMp4};
use crate::error::MP4Error;
use async_trait::async_trait;
use crate::bytes_write::{Mp4Writable, WriteMp4};

#[derive(Copy, Clone, Eq, PartialEq, Hash)]
pub struct PaddedByte<const N: usize, const V: usize = 0>(u8);

impl<const N: usize, const V: usize> Default for PaddedByte<N, V> {
    fn default() -> Self {
        Self::from(0)
    }
}

impl<const N: usize, const V: usize> AsPrimitive<usize> for PaddedByte<N, V> {
    fn as_(self) -> usize {
        let u: u8 = self.as_();
        u as usize
    }
}

impl<const N: usize, const V: usize> AsPrimitive<PaddedByte<N, V>> for usize  {
    fn as_(self) -> PaddedByte<N, V> {
        let u: u8 = self.as_();
        u.as_()
    }
}

impl<const N: usize, const V: usize> From<u8> for PaddedByte<N, V> {
    fn from(value: u8) -> Self {
        value.as_()
    }
}

impl<const N: usize, const V: usize> From<PaddedByte<N, V>> for u8 {
    fn from(value:  PaddedByte<N, V>) -> Self {
        value.as_()
    }
}

#[async_trait]
impl<const N: usize, const V: usize> Mp4Readable for PaddedByte<N, V> {
    async fn read<R: ReadMp4>(reader: &mut R) -> Result<Self, MP4Error> {
        Ok(Self(reader.read::<u8>().await? & Self::MASK | Self::PAD))
    }
}

impl<const N: usize, const V: usize> Mp4Writable for PaddedByte<N, V> {
    fn byte_size(&self) -> usize {
        self.0.byte_size()
    }

    fn write<W: WriteMp4>(&self, writer: &mut W) -> Result<usize, MP4Error> {
        self.0.write(writer)
    }
}

impl<const N: usize, const V: usize> Debug for PaddedByte<N, V> {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        let u : u8 = self.as_();
        Debug::fmt(&u, f)
    }
}

impl<const N: usize, const V: usize> PaddedByte<N, V> {
    const MASK: u8 = (1u8 << (8 - N)).wrapping_sub(1);
    const PAD: u8 = if V == 0 { 0 } else { u8::MAX & !Self::MASK };
}

impl<const N: usize, const V: usize> AsPrimitive<u8> for PaddedByte<N, V> {
    fn as_(self) -> u8 {
        self.0 & Self::MASK
    }
}

impl<const N: usize, const V: usize> AsPrimitive<PaddedByte<N, V>> for u8 {
    fn as_(self) -> PaddedByte<N, V> {
        PaddedByte::<N, V>(self & PaddedByte::<N, V>::MASK | PaddedByte::<N, V>::PAD)
    }
}

#[cfg(test)]
mod test {
    use crate::types::padded_byte::PaddedByte;

    #[test]
    fn test_mask() {
        assert_eq!(PaddedByte::<6, 1>::from(0).0, 0b11111100);
        assert_eq!(PaddedByte::<6, 1>::from(3).0, 0b11111111);
    }

}