node-bindgen 2.1.0

easy way to write nodejs module using rust
Documentation

<h1 align="center">node-bindgen</h1>
<div align="center">
 <strong>
   Easy way to write native Node.js module using idiomatic Rust
 </strong>
</div>

<br />

<div align="center">
   <!-- CI status -->
  <a href="https://github.com/infinyon/node-bindgen/actions">
    <img src="https://github.com/infinyon/node-bindgen/workflows/CI/badge.svg"
      alt="CI Status" />
  </a>
  <!-- Crates version -->
  <a href="https://crates.io/crates/node-bindgen">
    <img src="https://img.shields.io/crates/v/node-bindgen?style=flat-square"
    alt="Crates.io version" />
  </a>
  <!-- Downloads -->
  <a href="https://crates.io/crates/node-bindgen">
    <img src="https://img.shields.io/crates/d/node-bindgen.svg?style=flat-square"
      alt="Download" />
  </a>
  <!-- docs.rs docs -->
  <a href="https://docs.rs/node-bindgen">
    <img src="https://img.shields.io/badge/docs-latest-blue.svg?style=flat-square"
      alt="docs.rs docs" />
  </a>

  <a href="https://discord.gg/m48dGA">
    <img src="https://img.shields.io/discord/695712741381636168.svg?logo=discord&style=flat-square"
      alt="chat" />
  </a>
</div>


## Features

- __Easy:__ Just write idiomatic Rust code, node-bindgen take care of generating Node.js FFI wrapper codes.
- __Safe:__ Node.js arguments are checked automatically based on Rust types.
- __Async:__ Support Async Rust.  Async codes are translated into Node.js promises.
- __Class:__ Rust struct can be access using Node.js classes.
- __Stream:__ Implement Node.js stream using Rust
- __N-API:__ Use Node.js N-API which means you don't have to recompile your module. 

# Compatibility with Node.js version

This project uses v5 of Node N-API.  Please see following [compatibility](https://nodejs.org/api/n-api.html#n_api_n_api_version_matrix) matrix.

Following OS are supported:
* Linux
* MacOs
* Windows



# Why node-bindgen?

Writing native node-js requires lots of boiler plate code.  Node-bindgen generates external "C" glue code from rust code including native module registration.  This make it writing node-js module easy and fun.  

Node-bi

# Getting started

## CLI Installation

Install nj-cli command line which will be used to generate native library.

```
cargo install nj-cli
```

This is one time step.

## Configuring Cargo.toml

Add two dependencies to your projects' ```Cargo.toml```.  

Add ```node-bindgen``` as a regular dependency (as below):
```
[dependencies]
node-bindgen = { version = "2.0.0-beta.1" }
```

Then add ```node-bindgen```'s procedure macro to your build-dependencies as below:
```
[build-dependencies]
node-bindgen = { path = "../../", features = ["build"] }
```

Then update crate type to ```cdylib``` to generate node.js compatible native module:
```
[lib]
crate-type = ["cdylib"]
```

# Example

A simple functional example which add two integers.  Noticed that you don't need to worry about JS conversion.


```rust

use node_bindgen::derive::node_bindgen;

/// add two integer
#[node_bindgen]
fn sum(first: i32, second: i32) -> i32 {        
    first + second
}

```

## Building native library

To build node.js library, using ```nj-cli``` to build:

```
nj-cli build
```

This will generate Node.js module in "./dist" folder.


## Using in Node.js

Then in the Node.js, rust function can invoked as normal node.js function:

```js
$ node
Welcome to Node.js v14.0.0.
Type ".help" for more information.
> let addon = require('./dist');
undefined
> addon.sum(2,3)
5
> 
```


# Features

## Function name or method can be renamed instead of default mapping

```rust
#[node_bindgen(name="multiply")]
fn mul(first: i32,second: i32) -> i32 {        
    first * second 
}
```

Rust function mul is re-mapped as ```multiply```

## Optional argument

Argument can be skipped if it is marked as optional
```rust
#[node_bindgen]
fn sum(first: i32, second: Option<i32>) -> i32 {        
    first + second.unwrap_or(0)
}
```
Then sum can be invoked as
```sum(10)``` or ```sum(10,20)```


##  Callback

JS callback are mapped as Rust closure

```rust
#[node_bindgen]
fn hello<F: Fn(String)>(first: f64, second: F) {

    let msg = format!("argument is: {}", first);

    second(msg);
}
```

from node:

```js
let addon = require('./dist');

addon.hello(2,function(msg){
  assert.equal(msg,"argument is: 2");
  console.log(msg);  // print out argument is 2
});
```

Callback are supported in Async rust as well.

## Support for Async Rust

Async rust function is mapped to Node.js promise.

```rust

use std::time::Duration;
use flv_future_aio::time::sleep;
use node_bindgen::derive::node_bindgen;


#[node_bindgen]
async fn hello(arg: f64) -> f64 {
    println!("sleeping");
    sleep(Duration::from_secs(1)).await;
    println!("woke and adding 10.0");
    arg + 10.0
}
```

```js
let addon = require('./dist');

addon.hello(5).then((val) => {
  console.log("future value is %s",val);
});

```


## JavaScript class

JavaScript class is supported.

```rust

struct MyClass {
    val: f64,
}


#[node_bindgen]
impl MyClass {

    #[node_bindgen(constructor)]
    fn new(val: f64) -> Self {
        Self { val }
    }

    #[node_bindgen]
    fn plus_one(&self) -> f64 {
        self.val + 1.0
    }

    #[node_bindgen(getter)]
    fn value(&self) -> f64 {
        self.val
    }
}
```

```js
let addon = require('./dist');
const assert = require('assert');

let obj = new addon.MyObject(10);
assert.equal(obj.value,10,"verify value works");
assert.equal(obj.plusOne(),11);
```

There are more features in the examples folder