A rust library that parses and reconstructs sketchware projects
swrs is (my first) rust library that can parse and reconstruct Sketchware projects easily. You can use the provided apis (crate::api
) to modify parsed Sketchware projects and convert them back into a raw sketchware project without much hassle!
This library is in alpha, and only supports regular Sketchware projects; this library has not been tested with modded projects (although I do have a plan to support it sometime in the future). This library has been tested with multiple projects off of Sketchub and parsing and reconstruction worked flawlessly.
It's important to take note that this swrs
library is composed of two parts: parser
and api
.
parser
is the part where raw sketchware projects are then being parsed into a structure that still retains their raw form but with rust types. It's output is aswrs::parser::SketchwareProject
api
is the part where theparser
models are then read and interpreted in a way in order to provide high level apis of collecting data and modifying the project. It's output is aswrs::api::SketchwareProject
Sketchware projects starts from being parsed by the parser
(here) into rust structs and then piped onto api
(here) to provide high-level APIs like iterating through blocks, substacks, view tree, etc.
Add swrs to your dependencies table in Cargo.toml
:
[dependencies]
swrs = "0.1.1"
// First you'll need to make a RawSketchwareProject struct instance
// which contains unencrypted raw data of a Sketchware project
let raw = RawSketchwareProject::from_encrypted(
std::fs::read(Path::new("path/to/project")),
std::fs::read(Path::new("path/to/file")),
...
);
// Then you'll have to parse it
let parsed = ParserSketchwareProject::parse_from(raw).except("Corrupted sketchware project");
// !! NOTE: ParserSketchwareProject is [`swrs::parser::SketchwareProject`] !!
// it's type aliased because it has the same name as in `swrs::api::SketchwareProject`
// And convert it to an API object so that you can modify it easily
let project = SketchwareProject::try_from(parsed).except("Corrupted sketchware project");
// There you have it!
println!("Screens:");
for screen in &mut project.screens {
println!(" - {} has {} total events", screen.layout_name, screen.events.len());
// Add a boolean variable
screen.variables.insert("hello_world".to_string(), Variable {
name: "hello_world".to_string(),
r#type: VariableType::Boolean
});
// Add a block on onCreate
if let Some(on_create) = screen.events.iter_mut().find(|e| e.name == "onCreate") {
// I might need to make a better api for this lmao
on_create.code.push_block(Block {
id: BlockId(0), // id and next_block are set by the function
next_block: None,
sub_stack1: None,
sub_stack2: None,
color: Color::from_rgb(0xa0, 0x6f, 0x3d), // block color
op_code: "addSourceDirectly".to_string(),
content: BlockContent::parse_from(
"add source directly %s.inputOnly",
Some(vec!["// Hello asd from swrs!".to_string()]),
|_| unreachable!()
).unwrap(),
ret_type: Default::default(),
type_name: Default::default()
});
}
// And a lot more!
}