async_mp4/types/
padded_byte.rs

1use std::fmt::{Debug, Formatter};
2use num_traits::AsPrimitive;
3use crate::bytes_read::{Mp4Readable, ReadMp4};
4use crate::error::MP4Error;
5use async_trait::async_trait;
6use crate::bytes_write::{Mp4Writable, WriteMp4};
7
8#[derive(Copy, Clone, Eq, PartialEq, Hash)]
9pub struct PaddedByte<const N: usize, const V: usize = 0>(u8);
10
11impl<const N: usize, const V: usize> Default for PaddedByte<N, V> {
12    fn default() -> Self {
13        Self::from(0)
14    }
15}
16
17impl<const N: usize, const V: usize> AsPrimitive<usize> for PaddedByte<N, V> {
18    fn as_(self) -> usize {
19        let u: u8 = self.as_();
20        u as usize
21    }
22}
23
24impl<const N: usize, const V: usize> AsPrimitive<PaddedByte<N, V>> for usize  {
25    fn as_(self) -> PaddedByte<N, V> {
26        let u: u8 = self.as_();
27        u.as_()
28    }
29}
30
31impl<const N: usize, const V: usize> From<u8> for PaddedByte<N, V> {
32    fn from(value: u8) -> Self {
33        value.as_()
34    }
35}
36
37impl<const N: usize, const V: usize> From<PaddedByte<N, V>> for u8 {
38    fn from(value:  PaddedByte<N, V>) -> Self {
39        value.as_()
40    }
41}
42
43#[async_trait]
44impl<const N: usize, const V: usize> Mp4Readable for PaddedByte<N, V> {
45    async fn read<R: ReadMp4>(reader: &mut R) -> Result<Self, MP4Error> {
46        Ok(Self(reader.read::<u8>().await? & Self::MASK | Self::PAD))
47    }
48}
49
50impl<const N: usize, const V: usize> Mp4Writable for PaddedByte<N, V> {
51    fn byte_size(&self) -> usize {
52        self.0.byte_size()
53    }
54
55    fn write<W: WriteMp4>(&self, writer: &mut W) -> Result<usize, MP4Error> {
56        self.0.write(writer)
57    }
58}
59
60impl<const N: usize, const V: usize> Debug for PaddedByte<N, V> {
61    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
62        let u : u8 = self.as_();
63        Debug::fmt(&u, f)
64    }
65}
66
67impl<const N: usize, const V: usize> PaddedByte<N, V> {
68    const MASK: u8 = (1u8 << (8 - N)).wrapping_sub(1);
69    const PAD: u8 = if V == 0 { 0 } else { u8::MAX & !Self::MASK };
70}
71
72impl<const N: usize, const V: usize> AsPrimitive<u8> for PaddedByte<N, V> {
73    fn as_(self) -> u8 {
74        self.0 & Self::MASK
75    }
76}
77
78impl<const N: usize, const V: usize> AsPrimitive<PaddedByte<N, V>> for u8 {
79    fn as_(self) -> PaddedByte<N, V> {
80        PaddedByte::<N, V>(self & PaddedByte::<N, V>::MASK | PaddedByte::<N, V>::PAD)
81    }
82}
83
84#[cfg(test)]
85mod test {
86    use crate::types::padded_byte::PaddedByte;
87
88    #[test]
89    fn test_mask() {
90        assert_eq!(PaddedByte::<6, 1>::from(0).0, 0b11111100);
91        assert_eq!(PaddedByte::<6, 1>::from(3).0, 0b11111111);
92    }
93
94}