sb3_decoder/decoder/decoder.rs
1//! A decoder module for handling Scratch 3.0 project files (.sb3).
2
3use crate::{decoder::RawProject, error::DecodeError, structs::Project};
4
5/// A decoder for Scratch 3.0 project files (.sb3).
6///
7/// The [`Decoder`] struct provides functionality to decode `.sb3` files into Rust structs.
8pub struct Decoder {
9 archive: zip::ZipArchive<std::io::Cursor<Vec<u8>>>,
10}
11
12impl Decoder {
13 /// Creates a new [`Decoder`] from the provided bytes of a `.sb3` file.
14 ///
15 /// # Errors
16 /// Returns [`DecodeError::Zip`] if there is an error reading the ZIP archive.
17 pub(super) fn new(bytes: Vec<u8>) -> Result<Self, DecodeError> {
18 let cursor = std::io::Cursor::new(bytes);
19 let archive = zip::ZipArchive::new(cursor)?;
20 Ok(Self { archive })
21 }
22
23 /// Decodes the `.sb3` file and returns the project data as a [`RawProject`] struct.
24 ///
25 /// # Errors
26 /// Returns [`DecodeError::Json`] if there is an error parsing the JSON data.
27 pub fn decode_raw(&mut self) -> Result<RawProject, DecodeError> {
28 let project_file = self.archive.by_name("project.json")?;
29 let raw_project: RawProject = serde_json::from_reader(project_file)?;
30 Ok(raw_project)
31 }
32
33 /// Decodes the `.sb3` file and returns the project data as a [`Project`] struct.
34 ///
35 /// # Errors
36 /// Returns [`DecodeError::Json`] if there is an error parsing the JSON data.
37 /// Returns [`DecodeError::NotFound`] if something expected is not found in the archive or in
38 /// the JSON data.
39 pub fn decode(&mut self) -> Result<Project, DecodeError> {
40 let raw_project = self.decode_raw()?;
41 let project = Project::new(raw_project, &mut self.archive)?;
42 Ok(project)
43 }
44}