factorio-codegen 0.1.2

Lua code generator for factorio-rs
Documentation
mod common;

use common::must_ok;
use factorio_codegen::LuaGenerator;
use factorio_ir::{
    block::Block,
    expression::Expression,
    function::{Function, Parameter},
    module::{Module, Symbol},
    scope::Scope,
    stage::Stage,
    statement::Statement,
    structure::{Struct, StructField},
    r#type::Type,
};

#[test]
fn generates_struct_as_table_with_methods() {
    let module = Module {
        name: "player".to_string(),
        stage: Stage::Control,
        body: Block { statements: vec![] },
        imports: vec![],
        submodules: vec![],
        locales: vec![],
        symbols: vec![Symbol {
            scope: Scope::Public,
            statement: Statement::StructDecl(Struct {
                name: "MyPlayer".to_string(),
                fields: vec![StructField {
                    name: "health".to_string(),
                    ty: Type::Int,
                    source_type: None,
                }],
                constants: vec![],
                methods: vec![
                    Function {
                        name: "get_health".to_string(),
                        params: vec![Parameter {
                            name: "self".to_string(),
                            r#type: Type::Void,
                            source_type: None,
                        }],
                        body: Block {
                            statements: vec![Statement::Return(Some(Expression::FieldAccess {
                                base: Box::new(Expression::Identifier("self".to_string())),
                                field: "health".to_string(),
                            }))],
                        },
                        doc: None,
                        debug: None,
                        event: None,
                        event_filter: None,
                    },
                    Function {
                        name: "set_health".to_string(),
                        params: vec![
                            Parameter {
                                name: "self".to_string(),
                                r#type: Type::Void,
                                source_type: None,
                            },
                            Parameter {
                                name: "health".to_string(),
                                r#type: Type::Int,
                                source_type: None,
                            },
                        ],
                        body: Block {
                            statements: vec![Statement::Assignment {
                                target: Expression::FieldAccess {
                                    base: Box::new(Expression::Identifier("self".to_string())),
                                    field: "health".to_string(),
                                },
                                value: Expression::Identifier("health".to_string()),
                            }],
                        },
                        doc: None,
                        debug: None,
                        event: None,
                        event_filter: None,
                    },
                ],
                doc: None,
                debug: None,
            }),
        }],
    };

    let output = must_ok(LuaGenerator::new().generate_module(&module));

    assert_eq!(
        output,
        concat!(
            "-- Generated by factorio-rs@0.1.2\n",
            "-- Module: `player`\n",
            "local player = {}\n",
            "player.MyPlayer = {}\n",
            "function player.MyPlayer:get_health()\n",
            "\treturn self.health\n",
            "end\n",
            "function player.MyPlayer:set_health(health)\n",
            "\tself.health = health\n",
            "end\n",
            "return player\n",
        )
    );
}

#[test]
fn generates_private_struct_as_local_table() {
    let module = Module {
        name: "player".to_string(),
        stage: Stage::Control,
        body: Block {
            statements: vec![Statement::StructDecl(Struct {
                name: "MyPlayer".to_string(),
                fields: vec![],
                constants: vec![],
                methods: vec![Function {
                    name: "new".to_string(),
                    params: vec![],
                    body: Block { statements: vec![] },
                    doc: None,
                    debug: None,
                    event: None,
                    event_filter: None,
                }],
                doc: None,
                debug: None,
            })],
        },
        imports: vec![],
        submodules: vec![],
        locales: vec![],
        symbols: vec![],
    };

    let output = must_ok(LuaGenerator::new().generate_module(&module));

    assert!(output.contains("local MyPlayer = {}"));
    assert!(output.contains("function MyPlayer.new()"));
}