napi-derive 0.1.0

#[derive(NapiArgs)] for napi crate
Documentation

Node.js N-API for Rust! [work in progress]

Build Status

High-level N-API bindings for Node.js addons written in Rust.

Warning: this is a proof-of-concept implementation that's not intended for use yet. The project is under initial phase of development, the API is a quite sketchy and is going to be refactored heavily. If you are interested in contributing, though, it is super welcome!

The project is covered by a Code of Conduct.

Crates

  • napi-sys: low-level bindings to N-API generated from node_api.h using bindgen.
  • napi: high-level and rusty wrappers around napi-sys.
  • napi-derive: contains a procedural macro that allows to construct typesafe structures that represent N-API callback parameters and automatically validate the arguments that JavaScript code passes in.

Example

Check out https://github.com/aqrln/napi-rs/tree/master/example to see the full source code and project structure of this example. (TODO: initialize the module from Rust too).

lib.rs

#[macro_use]
extern crate napi;
#[macro_use]
extern crate napi_derive;

use napi::{NapiEnv, NapiNumber, NapiResult, NapiUndefined};

#[derive(NapiArgs)]
struct HelloArgs;

fn hello<'a>(env: &'a NapiEnv, _: &HelloArgs) -> NapiResult<NapiUndefined<'a>> {
    println!("Hello from the Rust land!");
    NapiUndefined::new(env)
}

#[derive(NapiArgs)]
struct AddArgs<'a> {
    first: NapiNumber<'a>,
    second: NapiNumber<'a>,
}

fn add<'a>(env: &'a NapiEnv, args: &AddArgs<'a>) -> NapiResult<NapiNumber<'a>> {
    let first = args.first.to_i32()?;
    let second = args.second.to_i32()?;
    NapiNumber::from_i32(env, first + second)
}

napi_callback!(example_hello, hello);
napi_callback!(example_add, add);

example.js

'use strict';

const addon = require('./build/Release/example.node');

addon.hello();
console.log(addon.add(1, 2));