libwaj 0.4.1

The library to handle waj file, the pack format for web site.
Documentation
mod builder;
mod entry;
mod entry_type;
mod properties;

pub(crate) use builder::RealBuilder;
pub use builder::{Builder, FullBuilderTrait};
pub use entry::{Entry, EntryDef};
pub use entry_type::EntryType;
use jbk::reader::builder::{BuilderTrait, PropertyBuilderTrait};
use jbk::reader::Range;
pub use properties::{AllProperties, Property};

pub const VENDOR_ID: jbk::VendorId = jbk::VendorId::new([0x77, 0x61, 0x6a, 0x00]);

pub struct Comparator {
    store: jbk::reader::EntryStore,
    path_property: jbk::reader::builder::ArrayProperty,
}

impl Comparator {
    pub fn new(properties: &AllProperties) -> Self {
        Self {
            store: properties.store.clone(),
            path_property: properties.path_property.clone(),
        }
    }

    pub fn compare_with<'a>(&'a self, component: &'a [u8]) -> EntryCompare<'a> {
        EntryCompare {
            comparator: self,
            path_value: component,
        }
    }
}

pub struct EntryCompare<'a> {
    comparator: &'a Comparator,
    path_value: &'a [u8],
}

impl jbk::reader::CompareTrait for EntryCompare<'_> {
    fn compare_entry(&self, idx: jbk::EntryIdx) -> jbk::Result<std::cmp::Ordering> {
        let reader = self
            .comparator
            .store
            .get_entry_reader(idx)
            .expect("idx should be valid");
        let entry_path = self.comparator.path_property.create(&reader)?;
        entry_path.cmp(self.path_value)
    }
    fn ordered(&self) -> bool {
        true
    }
}

pub struct ReadEntry<'builder, Builder: BuilderTrait> {
    builder: &'builder Builder,
    current: jbk::EntryIdx,
    end: jbk::EntryIdx,
}

impl<'builder, Builder: BuilderTrait> ReadEntry<'builder, Builder> {
    pub fn new<R: Range>(range: &R, builder: &'builder Builder) -> Self {
        let end = range.offset() + range.count();
        Self {
            builder,
            current: range.offset(),
            end,
        }
    }
}

impl<'builder, Builder: BuilderTrait> Iterator for ReadEntry<'builder, Builder> {
    type Item = Result<Builder::Entry, Builder::Error>;

    fn next(&mut self) -> Option<Self::Item> {
        if self.current == self.end {
            None
        } else {
            let entry = self
                .builder
                .create_entry(self.current)
                .transpose()
                .expect("self.current is valid");
            self.current += 1;
            Some(entry)
        }
    }
}