sarc/
lib.rs

1//! A simple to use library for reading/writing SARC and SZS (yaz0 compressed SARCs) in Rust.
2//! 
3//! ```rust
4//! // yaz0 and non-yaz0 sarcs can be read the same way
5//! let sarc = SarcFile::read_from_file("Animal_Fish_A.sbactorpack").unwrap();
6//! 
7//! // iterate through files in the sarc and print out a file list
8//! for file in &sarc.files {
9//!     println!("Name: {:?} | Size: {}", file.name, file.data.len());
10//! }
11//! 
12//! // write as yaz0 compressed sarc
13//! sarc.write_to_compressed_file("animal_test.sarc").unwrap();
14//! ```
15//!
16//! ### Features
17//!
18//! `yaz0_sarc` - support reading/writing yaz0-compressed sarc files
19//! `zstd_sarc` - support reading/writing yaz0-compressed sarc files
20pub mod parser;
21pub mod writer;
22
23/// An in-memory representation of a Sarc archive
24#[derive(Debug)]
25pub struct SarcFile {
26    pub byte_order: Endian,
27    pub files: Vec<SarcEntry>
28}
29
30/// A file contained within a Sarc archive
31pub struct SarcEntry {
32    /// Filename of the file within the Sarc
33    pub name: Option<String>,
34    /// Data of the file
35    pub data: Vec<u8>
36}
37
38impl std::fmt::Debug for SarcEntry {
39    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
40        write!(f, "{:?}", self.name)
41    }
42}
43
44/// Byte order of the give sarc file
45#[repr(u16)]
46#[derive(Debug)]
47pub enum Endian {
48    Big = 0xFEFF,
49    Little = 0xFFFE,
50}
51
52const KEY: u32 = 0x00000065;
53
54/// Hashing function used for hashing sfat strings
55pub fn sfat_hash(string: &str) -> u32 {
56    string.chars().fold(0u32, |hash, c| hash.wrapping_mul(KEY) + (c as u32))
57}
58
59#[cfg(test)]
60mod tests {
61    use super::SarcFile;
62
63    #[test]
64    fn file_test() {
65        let file = SarcFile::read_from_file("Animal_Fish_A.sbactorpack").unwrap();
66        #[cfg(feature = "yaz0_sarc")]
67        file.write_to_compressed_file("animal_test.sarc").unwrap();
68        dbg!(file);
69    }
70
71    #[test]
72    fn file_test_2() {
73        let file = SarcFile::read_from_file("/home/jam/a/downloads/animal_crossing/horizons/romfs/String.szs").unwrap();
74        file.write_to_file("test.sarc").unwrap();
75        dbg!(file);
76    }
77}