#解析 #重构 #解析器 #sketchware #sw

swrs

一个简单的Rust库,可以读取并解析Sketchware项目

1个不稳定版本

0.1.1 2022年11月6日
0.1.0 2022年11月6日

#1601解析器实现

MIT 许可证

220KB
5K SLoC

swrs

一个解析并重构Sketchware项目的Rust库

swrs是我(第一个)可以轻松解析和重构Sketchware项目的Rust库。您可以使用提供的API(crate::api)来修改解析后的Sketchware项目,并将其无障碍地转换回原始Sketchware项目!

此库处于alpha阶段,仅支持常规Sketchware项目;此库尚未与mod项目进行测试(尽管我计划在将来某个时间支持它)。此库已在Sketchub上的多个项目上进行测试,解析和重构工作无任何问题。

结构

请注意,此swrs库由两部分组成:parserapi

  • parser部分将原始Sketchware项目解析成保留了原始形式但使用Rust类型的结构。其输出是一个swrs::parser::SketchwareProject
  • api部分读取并解释由parser生成的模型,以便提供高级API来收集数据并修改项目。其输出是一个swrs::api::SketchwareProject

Sketchware项目从被parser这里)解析为Rust结构开始,然后通过管道传输到api这里)以提供高级API,如遍历块、子栈、视图树等。

安装

将swrs添加到您的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!
}

依赖项

~3.5-4.5MB
~84K SLoC