async_mp4/types/
duration.rs

1use async_trait::async_trait;
2use crate::bytes_read::{Mp4VersionedReadable, ReadMp4};
3use crate::bytes_reserve::Mp4Reservable;
4use crate::bytes_write::{FlagTrait, Mp4VersionedWritable, Mp4Writable, WriteMp4};
5use crate::error::MP4Error;
6
7#[derive(Copy, Clone, Debug, Default, Ord, PartialOrd, Eq, PartialEq, Hash)]
8pub struct Mp4Duration(pub Option<u64>);
9
10#[async_trait]
11impl<F: FlagTrait> Mp4VersionedReadable<F> for Mp4Duration {
12    async fn versioned_read<R: ReadMp4 + ?Sized>(version: u8, _: F, reader: &mut R) -> Result<Self, MP4Error> {
13        Ok(Self(match version {
14            0 => match reader.read::<u32>().await? {
15                u32::MAX => None,
16                value=> Some(value as u64)
17            },
18            _ => match reader.read().await? {
19                u64::MAX => None,
20                value=> Some(value)
21            }
22        }))
23    }
24}
25
26impl<F: FlagTrait> Mp4VersionedWritable<F> for Mp4Duration {
27    fn required_version(&self) -> u8 {
28        if let Some(duration) = self.0 {
29           if duration >= u32::MAX as u64 { 1 } else { 0 }
30        } else {
31            0
32        }
33    }
34
35    fn versioned_byte_size(&self, version: u8, _: F) -> usize {
36        match version {
37            0 => u32::BYTE_SIZE,
38            _ => u64::BYTE_SIZE
39        }
40    }
41
42    fn versioned_write<W: WriteMp4>(&self, version: u8, _: F, writer: &mut W) -> Result<usize, MP4Error> {
43        Ok(match version {
44            0 => if let Some(value) = self.0 { value as u32} else { u32::MAX }.write(writer)?,
45            _ => if let Some(value) = self.0 { value } else { u64::MAX }.write(writer)?
46        })
47    }
48}