unitypkg_core/
unpack.rs

1use std::{
2    fs::{create_dir_all, File},
3    io::{self, Write},
4    path::PathBuf,
5};
6
7use crate::Package;
8
9pub fn unpack_package(package: Package, directory: &PathBuf) -> Result<(), io::Error> {
10    create_dir_all(directory)?;
11
12    for asset in package.assets.values() {
13        let asset_file = directory.join(&asset.pathname);
14        let meta_file = asset_file.with_extension("meta");
15
16        if let Some(parent) = asset_file.parent() {
17            create_dir_all(parent)?;
18        }
19
20        if let Some(data) = &asset.data {
21            let mut file = File::create(&asset_file).unwrap();
22            file.write_all(data)?;
23        }
24
25        if let Some(meta) = &asset.meta {
26            let mut file = File::create(&meta_file).unwrap();
27            file.write_all(meta)?;
28        }
29    }
30
31    Ok(())
32}
33
34#[cfg(test)]
35mod test {
36    use std::{fs::remove_dir_all, io::Read};
37
38    use tempfile::tempdir;
39    use uuid::Uuid;
40
41    use super::*;
42    use crate::PackageAssetBuilder;
43
44    #[test]
45    fn unpack() {
46        let temp_dir = tempdir().unwrap().into_path();
47
48        let mut package = Package::new();
49        let uuid = Uuid::new_v4();
50        let mut builder = PackageAssetBuilder::default();
51        builder.pathname = Some("Assets/SomeMaterial".to_string());
52        builder.data = Some(vec![9, 10, 11, 12]);
53        builder.meta = Some(vec![5, 6, 7, 8]);
54        package.assets.insert(uuid, builder.build());
55
56        unpack_package(package, &temp_dir).unwrap();
57
58        let asset_file = temp_dir.join("Assets/SomeMaterial");
59        let meta_file = asset_file.with_extension("meta");
60
61        assert!(asset_file.exists());
62        assert!(meta_file.exists());
63
64        let mut data = Vec::new();
65        File::open(&asset_file)
66            .unwrap()
67            .read_to_end(&mut data)
68            .unwrap();
69        assert_eq!(data, vec![9, 10, 11, 12]);
70
71        let mut meta = Vec::new();
72        File::open(meta_file)
73            .unwrap()
74            .read_to_end(&mut meta)
75            .unwrap();
76        assert_eq!(meta, vec![5, 6, 7, 8]);
77
78        remove_dir_all(temp_dir).unwrap();
79    }
80}