async_mp4/types/
padded_byte.rs1use 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}