ngrs 0.1.3

A New Rust bindings for GNU Guile Scheme
// SPDX-License-Identifier: MIT OR Apache-2.0
// SPDX-FileCopyrightText: 2024 MinkieYume <minkieyume@yumieko.com>
use ngrs::*;
use std::sync::Once;
use std::env;
use std::path::PathBuf;

static INIT: Once = Once::new();

#[ctor::ctor]
fn global_init() {
    INIT.call_once(|| {
        Runtime::initialize();
    });
}

#[test]
fn can_eval_string() {
    let runtime = Runtime::new();
    runtime.eval_string("(+ 1 2 3)");
    assert!(true, "Evaluated successfully");
}

#[test]
fn can_eval_with_guile() {
    with_guile(|vm| {
        vm.eval_string("(+ 1 2 3)");            
    });
}

#[test]
fn can_eval_get_value() {
    with_guile(|vm| {
        let value = vm.eval_string("(+ 1 2 3)");
        println!("Evaluated value: {:?}", value);
    });
}

#[test]
fn can_eval_and_get_number() {
    with_guile(|vm| {
        let value:i32 = vm.eval_string("(+ 1 2 3)").try_into().unwrap();
        assert_eq!(value, 6);
    });
}

#[test]
fn can_eval_and_get_string() {
    with_guile(|vm| {
        let value:String = vm.eval_string("(string-append \"kkp\" \"PPL\")").try_into().unwrap();
        assert_eq!(value, "kkpPPL");
    });
}

#[test]
fn can_load_file() {    
    with_guile(|vm| {
        let current_dir:PathBuf = env::current_dir().unwrap();
        let path = current_dir.join("scm/test-loadfile.scm");
        let filename = path.to_str().unwrap();
        let scm = vm.primitive_load(filename);
        assert_eq!(scm.to_string(), "6");
    });
}

#[test]
fn can_define() {    
    with_guile(|vm| {
        vm.define("num", &SCM::from(42_i32));
        let scm = vm.eval_string("num");
        let num:i32 = scm.try_into().unwrap();
        assert_eq!(num, 42_i32);
    });
}

#[test]
fn can_apply() {
    with_guile(|vm| {
        let proc = SCM::from_var_name("+");
        let lst: Pair = Pair::new(SCM::from(1),
            SCM::from(Pair::new(SCM::from(2), SCM::from(Pair::new(SCM::from(3), SCM::eol())))));
        let result:i32 = vm.apply(&proc, &SCMOrPair::Pair(lst)).try_into().unwrap();
        assert_eq!(result, 6);
    });
}

#[test]
fn can_define_module() {
    with_guile(|vm| {
        vm.define_module("chiko plustwo", |mvm| {
            scm_fn! {
                fn scm_hello_test(scm1:SCM,scm2:SCM) -> SCM {
                    println!("Hello from Rust procedure!");
                    let val1:i32 = scm1.try_into().unwrap();
                    let val2:i32 = scm2.try_into().unwrap();
                    SCM::from(val1 + val2)
                }
            }
            define_procedure!("plus-two", 2,0,false, scm_hello_test);
            mvm.module_export("plus-two");
        });
        let proc = SCM::from_module_public("chiko plustwo", "plus-two");
        let result:i32 = vm.apply(&proc, &Pair::from(vec![3_i32, 4_i32]).into()).try_into().unwrap();
        assert_eq!(result, 7);
    });
}