alxolr

posts about software engineering craft

How to process javascript array of objects with rust neon bindings

How to process javascript array of objects with rust neon bindings

Intro

In this tutorial, I am creating a native node.js module, which will process a javascript array of objects and log the keys and the values of each element.

Problem

Neon and Rust Lang are a fantastic combo in the arsenal of every nodejs developer.

Unfortunately, as they are both quite young, the lack of documentation is a significant pain.

Code

Assuming we have a collection of javascript objects with the same structure, and we want to debug and operate with the values of thoses objects. In javascript we would've use console.log() but using neon it's not that simple.

function debugArrayOfObjects(items: object[]) {
  // console.log(items);
}
use neon::prelude::*;
//...

fn debug_array_of_objects(mut cx: FunctionContext) -> JsResult<JsUndefined> {
    // the way to extract first argument out of the function
    let collection_js = cx.argument::<JsArray>(0)?;

    // this part transform the Js Array into Rust Vector
    let collection_rust: Vec<Handle<JsValue>> = collection_js.to_vec(&mut cx)?;

    // we get first item from the collection
    let first_item: &Handle<JsValue> = collection_rust.first().unwrap();

    // we try to get the object keys to be able to iterate the values
    let object_keys_js: Handle<JsArray> = first_item
        // this function tries to cast the JsValue which can be any into an object
        .downcast::<JsObject>()
        .unwrap()
        .get_own_property_names(&mut cx)?;

    // now we need transform again the Handle<JsArray> into some Vec<String> using
    let object_keys_rust: Vec<Handle<JsValue>> = object_keys_js.to_vec(&mut cx)?;

    for item in collection_rust {
        println!("{{");
        let item_rust = item.downcast::<JsObject>().unwrap();

        for key in &object_keys_rust {
            let key_value = key.to_string(&mut cx)?.value();
            let item_value = item_rust.get(&mut cx, *key)?.to_string(&mut cx)?.value();
            println!("  {}: {}", key_value, item_value);
        }
        println!("}}");
    }

    Ok(cx.undefined())
}

register_module!(mut cx, {
    cx.export_function(r#"debugArrayOfObjects"#, debug_array_of_objects)
});

I hope that this article was helpful. If you like it, please share it with your friends and leave a comment; I will gladly answer all the questions.

Related articles

×