sb3_decoder/decoder/decoder_builder.rs
1//! A builder for creating a Decoder from either a file or in-memory bytes.
2//!
3//! # Example
4//! ```no_run
5//! # use sb3_decoder::prelude::*;
6//! let builder = DecoderBuilder::new()
7//! .use_file("path/to/project.sb3");
8//!
9//! let decoder = match builder.build() {
10//! Ok(decoder) => decoder,
11//! Err(e) => panic!("Failed to build decoder: {}", e),
12//! };
13//! ```
14
15use std::path::PathBuf;
16
17use crate::{decoder::Decoder, error::BuilderError};
18
19/// Represents the source of the .sb3 data.
20enum Source {
21 /// No source specified.
22 None,
23
24 /// Source from a file path.
25 File(PathBuf),
26
27 /// Source from in-memory bytes.
28 Memory(Vec<u8>),
29}
30
31/// A builder for creating a [`Decoder`] from either a file or in-memory bytes.
32///
33/// # Example
34/// ```no_run
35/// # use sb3_decoder::prelude::*;
36/// let builder = DecoderBuilder::new()
37/// .use_file("path/to/project.sb3");
38///
39/// let decoder = match builder.build() {
40/// Ok(decoder) => decoder,
41/// Err(e) => panic!("Failed to build decoder: {}", e),
42/// };
43/// ```
44pub struct DecoderBuilder {
45 source: Source,
46}
47
48impl Default for DecoderBuilder {
49 fn default() -> Self {
50 Self::new()
51 }
52}
53
54impl DecoderBuilder {
55 /// Creates a new [`DecoderBuilder`] instance with no source specified.
56 pub fn new() -> Self {
57 Self {
58 source: Source::None,
59 }
60 }
61
62 /// Specifies the source as a file path.
63 ///
64 /// # Example
65 /// ```no_run
66 /// # use sb3_decoder::prelude::*;
67 /// let builder = DecoderBuilder::new()
68 /// .use_file("path/to/project.sb3");
69 /// ```
70 pub fn use_file(mut self, path: impl Into<PathBuf>) -> Self {
71 self.source = Source::File(path.into());
72 self
73 }
74
75 /// Specifies the source as in-memory bytes.
76 ///
77 /// # Example
78 /// ```no_run
79 /// # use sb3_decoder::prelude::*;
80 /// let builder = DecoderBuilder::new()
81 /// # .use_bytes(&[]); /*
82 /// .use_bytes(include_bytes!("path/to/project.sb3"));
83 /// # */
84 /// ```
85 pub fn use_bytes(mut self, bytes: &[u8]) -> Self {
86 self.source = Source::Memory(bytes.to_vec());
87 self
88 }
89
90 /// Builds the [`Decoder`] from the specified source.
91 ///
92 /// # Example
93 /// ```no_run
94 /// # use sb3_decoder::prelude::*;
95 /// # let builder = DecoderBuilder::new()
96 /// # .use_file("path/to/project.sb3");
97 /// let decoder = match builder.build() {
98 /// Ok(decoder) => decoder,
99 /// Err(e) => panic!("Failed to build decoder: {}", e),
100 /// };
101 /// ```
102 ///
103 /// # Errors
104 /// Returns [`BuilderError::FileRead`] if there is an error reading the file.
105 /// Returns [`BuilderError::NoSource`] if no source was specified.
106 /// Returns [`BuilderError::Decode`] if there is an error creating the decoder.
107 pub fn build(self) -> Result<Decoder, BuilderError> {
108 let bytes = match self.source {
109 Source::File(path) => std::fs::read(path)?,
110 Source::Memory(data) => data,
111 Source::None => return Err(BuilderError::NoSource),
112 };
113
114 Ok(Decoder::new(bytes)?)
115 }
116}