dukbind 0.0.4

Raw duktape bindings for rust.
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
include!(concat!(env!("OUT_DIR"), "/duktape_bindings.rs"));
use std::ffi;
pub unsafe fn duk_create_heap_default() -> *mut duk_context {
    use std::ptr::null_mut;
    let ctx = duk_create_heap(None, None, None, null_mut(), None);
    unsafe extern "C" fn printc(c: *mut duk_context) -> i32 {
        let cstr = ffi::CStr::from_ptr(duk_to_string(c, 0));
        println!("{0}", cstr.to_str().unwrap());
        0
    }
    duk_push_global_function(ctx, "print", Some(printc), 1);
    ctx
}
pub unsafe fn duk_eval_string(ctx: *mut duk_context, code: &str) -> u32 {
    let filename = "input";
    duk_push_lstring(ctx, filename.as_ptr() as *const i8,
                        filename.len() as duk_size_t);
    duk_eval_raw(ctx, code.as_ptr() as *const i8,
                    code.len() as duk_size_t,
                    DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE |
                    DUK_COMPILE_SAFE) as u32
}
pub unsafe fn duk_push_global_function(ctx: *mut duk_context, name: &str, f: duk_c_function, args: i32) -> bool {
    duk_push_c_function(ctx, f, args);
    duk_put_global_lstring(ctx, name.as_ptr() as *const i8, name.len() as duk_size_t) == 0
}

extern "C" {
    /// A wrapper around duk_push_error_object, which relies on varargs in
    /// the original API.
    /// NOTE: Pulled from duktape crate duktape_sys/src/glue.rs
    pub fn duk_push_error_object_string(
        ctx: *mut duk_context, err_code: duk_errcode_t,
        filename: *const i8, line: duk_int_t,
        message: *const i8) -> duk_idx_t;
}

#[cfg(test)]
mod tests {
    #[test]
    fn test_eval() {
        use super::*;
        unsafe {
            // Pulled from duktape crate duktape_sys/src/lib.rs | Modified to compile.
            // Create a heap.
            let ctx = duk_create_heap_default();

            // Run a short code snippet.
            let code = "2+3";
            let result = duk_eval_string(ctx, code);
            assert_eq!(DUK_EXEC_SUCCESS, result);

            // Get the result and make sure it's correct.
            assert_eq!(1, duk_is_number(ctx, -1));
            assert_eq!(5.0, duk_get_number(ctx, -1));
            duk_pop(ctx);

            duk_destroy_heap(ctx);
        }
    }
}