mp4ameta 0.13.0

A library for reading and writing iTunes style MPEG-4 audio metadata.
Documentation
use super::*;

#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct Moov<'a> {
    pub state: State,
    pub mvhd: Mvhd,
    pub trak: Vec<Trak>,
    pub udta: Option<Udta<'a>>,
}

impl Atom for Moov<'_> {
    const FOURCC: Fourcc = MOVIE;
}

impl ParseAtom for Moov<'_> {
    fn parse_atom(
        reader: &mut (impl Read + Seek),
        cfg: &ParseConfig<'_>,
        size: Size,
    ) -> crate::Result<Self> {
        let bounds = find_bounds(reader, size)?;
        let mut parsed_bytes = 0;
        let mut mvhd = None;
        let mut trak = Vec::new();
        let mut udta = None;

        while parsed_bytes < size.content_len() {
            let remaining_bytes = size.content_len() - parsed_bytes;
            let head = head::parse(reader, remaining_bytes)?;

            match head.fourcc() {
                MOVIE_HEADER => mvhd = Some(Mvhd::parse(reader, cfg, head.size())?),
                TRACK if cfg.write || cfg.cfg.read_chapter_track || cfg.cfg.read_audio_info => {
                    trak.push(Trak::parse(reader, cfg, head.size())?)
                }
                USER_DATA if cfg.cfg.read_meta_items || cfg.cfg.read_chapter_list => {
                    udta = Some(Udta::parse(reader, cfg, head.size())?)
                }
                _ => reader.skip(head.content_len() as i64)?,
            }

            parsed_bytes += head.len();
        }

        let mvhd = mvhd.ok_or_else(|| {
            crate::Error::new(
                ErrorKind::AtomNotFound(MOVIE_HEADER),
                "Missing necessary data, no movie header (mvhd) atom found",
            )
        })?;

        let moov = Self { state: State::Existing(bounds), mvhd, trak, udta };

        Ok(moov)
    }
}

impl AtomSize for Moov<'_> {
    fn size(&self) -> Size {
        let content_len = self.mvhd.len()
            + self.trak.iter().map(Trak::len).sum::<u64>()
            + self.udta.len_or_zero();
        Size::from(content_len)
    }
}

impl SimpleCollectChanges for Moov<'_> {
    fn state(&self) -> &State {
        &self.state
    }

    fn existing<'a>(
        &'a self,
        level: u8,
        bounds: &'a AtomBounds,
        changes: &mut Vec<Change<'a>>,
    ) -> i64 {
        self.trak.iter().map(|a| a.collect_changes(bounds.end(), level, changes)).sum::<i64>()
            + self.udta.collect_changes(bounds.end(), level, changes)
    }

    fn atom_ref(&self) -> AtomRef<'_> {
        AtomRef::Moov(self)
    }
}