web_static_pack_packer/
pack.rs1use crate::{
4 common::{PACK_FILE_MAGIC, PACK_FILE_VERSION, file::File, pack::Pack, pack_path::PackPath},
5 file_pack_path::FilePackPath,
6};
7use anyhow::{Error, bail};
8use rkyv::{api::high::to_bytes_in, rancor, ser::writer::IoWriter, util::AlignedVec};
9use std::{
10 collections::{HashMap, hash_map},
11 fs, io,
12 path::Path,
13};
14
15#[derive(Debug)]
18pub struct Builder {
19 files_by_pack_path: HashMap<PackPath, File>,
20}
21impl Builder {
22 pub fn new() -> Self {
24 let files_by_pack_path = HashMap::<PackPath, File>::new();
25
26 Self { files_by_pack_path }
27 }
28
29 pub fn file_pack_path_add(
31 &mut self,
32 file_pack_path: FilePackPath,
33 ) -> Result<(), Error> {
34 let entry = match self.files_by_pack_path.entry(file_pack_path.pack_path) {
35 hash_map::Entry::Occupied(_entry) => {
36 bail!("file on specified path already exist");
37 }
38 hash_map::Entry::Vacant(entry) => entry,
39 };
40
41 entry.insert(file_pack_path.file);
42
43 Ok(())
44 }
45
46 pub fn file_pack_paths_add(
48 &mut self,
49 file_pack_paths: impl IntoIterator<Item = FilePackPath>,
50 ) -> Result<(), Error> {
51 file_pack_paths
52 .into_iter()
53 .try_for_each(|file_pack_path| self.file_pack_path_add(file_pack_path))?;
54
55 Ok(())
56 }
57
58 pub fn finalize(self) -> Pack {
60 Pack {
61 files_by_path: self.files_by_pack_path,
62 }
63 }
64}
65
66fn store(
67 pack: &Pack,
68 mut writer: impl io::Write,
69) -> Result<(), Error> {
70 writer.write_all(&PACK_FILE_MAGIC.to_ne_bytes())?;
73 writer.write_all(&PACK_FILE_VERSION.to_ne_bytes())?;
74 to_bytes_in::<_, rancor::Error>(pack, IoWriter::new(writer))?;
75
76 Ok(())
77}
78
79pub fn store_memory(pack: &Pack) -> Result<AlignedVec, Error> {
82 let mut buffer = AlignedVec::new();
83 store(pack, &mut buffer)?;
84 Ok(buffer)
85}
86
87pub fn store_file(
90 pack: &Pack,
91 path: &Path,
92) -> Result<(), Error> {
93 let mut file = fs::File::create(path)?;
94
95 store(pack, &mut file)?;
96
97 file.sync_all()?;
98 drop(file);
99
100 Ok(())
101}