1use crate::error::{BaseError, WajError, WajFormatError};
2
3use super::common::{AllProperties, Comparator, Entry, FullBuilderTrait, RealBuilder};
4use jbk::reader::Range;
5use std::path::Path;
6
7pub struct Waj {
8 container: jbk::reader::Container,
9 pub(crate) root_index: jbk::reader::Index,
10 pub(crate) properties: AllProperties,
11}
12
13impl std::ops::Deref for Waj {
14 type Target = jbk::reader::Container;
15 fn deref(&self) -> &Self::Target {
16 &self.container
17 }
18}
19
20fn create_properties(
21 container: &jbk::reader::Container,
22 index: &jbk::reader::Index,
23) -> Result<AllProperties, BaseError> {
24 AllProperties::new(
25 index.get_store(container.get_entry_storage())?,
26 container.get_value_storage(),
27 )
28}
29
30impl Waj {
31 pub fn new<P: AsRef<Path>>(file: P) -> Result<Self, WajError> {
32 let container = jbk::reader::Container::new(&file)?;
33 let root_index = container
34 .get_directory_pack()
35 .get_index_from_name("waj_entries")?
36 .ok_or(WajFormatError("No `waj_entries` in the archive"))?;
37 let properties = create_properties(&container, &root_index)?;
38
39 Ok(Self {
40 container,
41 root_index,
42 properties,
43 })
44 }
45
46 pub fn create_properties(
47 &self,
48 index: &jbk::reader::Index,
49 ) -> Result<AllProperties, BaseError> {
50 create_properties(&self.container, index)
51 }
52
53 pub fn get_entry<B>(&self, path: &str) -> Result<Entry<B::Entry>, WajError>
54 where
55 B: FullBuilderTrait,
56 {
57 let comparator = Comparator::new(&self.properties);
58 let builder = RealBuilder::<B>::new(&self.properties);
59 let current_range: jbk::EntryRange = (&self.root_index).into();
60 let comparator = comparator.compare_with(path.as_bytes());
61 match current_range.find(&comparator)? {
62 None => Err(WajError::PathNotFound(format!("Cannot found entry {path}"))),
63 Some(idx) => {
64 let entry = current_range
65 .get_entry(&builder, idx)?
66 .expect("idx should be valid");
67 Ok(entry)
68 }
69 }
70 }
71}