jubako 0.3.0

The reference implementation of the Jubako container format
Documentation
use super::properties::{CommonProperties, Properties, VariantProperties};
use crate::bases::Writable;
use crate::bases::*;
use crate::creator::directory_pack::EntryTrait;

#[derive(Debug)]
struct Entry {
    common: Properties,
    variants: Vec<Properties>,
    entry_size: u16,
}

impl Entry {
    fn new(common: CommonProperties, variants: Vec<VariantProperties>) -> Self {
        Self {
            common,
            variants: variants.into_iter().map(Properties::from).collect(),
            entry_size: 0,
        }
    }

    fn finalize(&mut self) {
        self.entry_size = self.common.entry_size();
        if !self.variants.is_empty() {
            let max_variant_size = self.variants.iter().map(|v| v.entry_size()).max().unwrap();
            self.entry_size += max_variant_size;
            for variant in &mut self.variants {
                variant.fill_to_size(max_variant_size);
            }
        }
    }

    fn write_entry(&self, entry: &dyn EntryTrait, stream: &mut dyn OutStream) -> Result<usize> {
        assert!(self.variants.is_empty() == entry.variant_id().is_none());
        let written = if self.variants.is_empty() {
            Properties::write_entry(self.common.iter(), entry, stream)?
        } else {
            let mut keys = self
                .common
                .iter()
                .chain(self.variants[entry.variant_id().unwrap().into_usize()].iter());
            Properties::write_entry(&mut keys, entry, stream)?
        };
        assert_eq!(written, self.entry_size as usize);
        Ok(written)
    }

    fn entry_size(&self) -> u16 {
        self.entry_size
    }

    fn key_count(&self) -> u8 {
        self.common.key_count() + self.variants.iter().map(|v| v.key_count()).sum::<u8>()
    }
}

impl Writable for Entry {
    fn write(&self, stream: &mut dyn OutStream) -> IoResult<usize> {
        let mut written = 0;
        written += stream.write_u16(self.entry_size())?;
        written += stream.write_u8(self.variants.len() as u8)?;
        written += stream.write_u8(self.key_count())?;
        written += self.common.write(stream)?;
        for variant in &self.variants {
            written += variant.write(stream)?;
        }
        Ok(written)
    }
}