Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: the deno_bindgen guide #101

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ target/
example/Cargo.lock
bindings.json
.DS_Store
docs/book/
158 changes: 2 additions & 156 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ in Rust.

### QuickStart

Annotate on top of Rust `fn`, `struct` and `enum` to make them avaiable to Deno.

```rust
// add.rs
use deno_bindgen::deno_bindgen;
Expand Down Expand Up @@ -38,160 +36,8 @@ import { add } from "./bindings/bindings.ts";
add({ a: 1, b: 2 }); // 3
```

### Installation

- Install the `deno_bindgen` CLI with Deno.

```shell
deno install -Afq -n deno_bindgen https://deno.land/x/deno_bindgen/cli.ts
```

Add the following dependencies to your crate.

```toml
# Cargo.toml
[dependencies]
deno_bindgen = "0.7.0"
serde = { version = "1", features = ["derive"] }
```

Change your `crate-type` to `cdylib` and set your package name as well.

```toml
[lib]
name = "___"
crate-type = ["cdylib"]
```

### Bindings

Put `#[deno_bindgen]` on top of a "serde-deriavable" struct, enum or fn.

#### `struct` (named fields)

These transform into Typescript `type`s.

```rust
// lib.rs
#[deno_bindgen]
pub struct A {
b: Vec<Vec<String>>,
}
```

becomes:

```typescript
// bindings/bindings.ts
export type A = {
b: Array<Array<string>>;
};
```

#### `enum`

Enums become `type` unions in Typescript.

```rust
#[deno_bindgen]
pub enum Event {
Quit,
MouseMove {
x: i32,
y: i32,
}
}
```

becomes:

```typescript
export type Enum =
| "quit"
| {
mouse_move: {
x: number;
y: number;
};
};
```

### `fn`

Functions are exposed through the FFI boundaries.

```rust
#[deno_bindgen]
fn greet(name: &str) {
println!("Hello, {}!", name);
}
```

becomes:

```typescript
export function greet(name: string) {
// ... glue code for calling the
// symbol.
}
```

Notes

- Use `#[deno_bindgen(non_blocking)]` attribute to call symbol without blocking
JS event loop. Exposed as an async funtion from bindings.

- Rust doc comments transform to JS docs.
```rust
#[deno_bindgen]
pub struct Me {
/// My name...
/// ...it is
name: String,
}
```
becomes:
```typescript
export type Me = {
/**
* My name...
* ...it is
*/
name: string;
};
```

- If the argument type of Rust is f32, the calculation result may be different.\
Number in Java Script is float64, when data is passed to Rust, it becomes
float32, so the number may change.\
e.g: `1.3 + 1.5` will be `2.799999952316284`

### CLI

The `deno_bindgen` CLI tool provides the following flags:

- Pass `--release` to create a release build.

- `--release=URL` will load library artifacts from a remote location. This is
useful for updating bindings for end users after a release:

```shell
deno_bindgen --release=https://github.com/littledivy/deno_sdl2/releases/download/0.2-alpha.1
```

Under the hood this uses [`x/plug`](https://deno.land/x/plug) to fetch and
cache the artifact.
### Documentation

Artifacts must be following the remote asset naming scheme, as follows:
See the deno_bindgen guide book [bindgen.deno.dev](https://bindgen.deno.dev) for full documentation and examples.

| OS | Arch | Naming |
| ------- | ------ | ------------------- |
| Windows | x86_64 | name.dll |
| Linux | x86_64 | libname.so |
| MacOS | x86_64 | libname.dylib |
| MacOS | arm64 | libname_arm64.dylib |

- Flags after `--` will be passed to `cargo build`. Example:
```shell
deno_bindgen -- --features "cool_stuff"
```
6 changes: 6 additions & 0 deletions docs/book.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[book]
authors = ["Divy Srivastava"]
language = "en"
multilingual = false
src = "src"
title = "deno_bindgen Guide"
9 changes: 9 additions & 0 deletions docs/src/SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Summary

- [Introduction](./intro.md)
- [Install](./install.md)
- [Examples](./examples.md)
- [Hello, World!](./examples/hello_world.md)
- [Working with structs](./examples/structs.md)
- [Working with enums](./examples/enums.md)
- [Multithreaded](./examples/nonblocking.md)
3 changes: 3 additions & 0 deletions docs/src/examples.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Examples

This subsection contains examples of using the `deno_bindgen` proc macro. These examples assume familiarity with basic Rust.
46 changes: 46 additions & 0 deletions docs/src/examples/enums.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Working with `enums`

The macro is capable of generating TypeScript definition and glue code for Rust enums. JS objects are serialized to JSON and converted to an enum using `serde_json`.

### [`src/lib.rs`](#)

```rust
use deno_bindgen::deno_bindgen;

#[deno_bindgen]
pub enum Event {
Quit,
MouseMove {
x: i32,
y: i32,
}
}

#[deno_bindgen]
fn do(event: Event) {
// ...
}
```

### [`mod.ts`](#)

```ts
import { do } from "./bindings/bindings.ts";

do("quit");
do({ mouseMove: { x: 10, y: 10 } })
```

### [`Cargo.toml`](#)

```toml
[package]
name = "enums"
version = "0.1.0"
edition = "2018"

[lib]
crate-type = ["cdylib"]

[dependencies]
deno_bindgen = "0.7.0"
35 changes: 35 additions & 0 deletions docs/src/examples/hello_world.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Hello, World!

### [`src/lib.rs`](#)

```rust
use deno_bindgen::deno_bindgen;

#[deno_bindgen]
pub fn greet(name: &str) {
println!("Hello, {}!", name);
}
```

### [`mod.ts`](#)

```ts
import { greet } from "bindings/bindings.ts";

greet("Deno");
```

### [`Cargo.toml`](#)

```toml
[package]
name = "hello_world"
version = "0.1.0"
edition = "2018"

[lib]
crate-type = ["cdylib"]

[dependencies]
deno_bindgen = "0.7.0"
```
41 changes: 41 additions & 0 deletions docs/src/examples/nonblocking.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Multithreaded

Deno FFI has a `nonblocking` mode. You can offload blocking I/O or heavy computation to a seperate thread. The call returns a JavaScript promise that
is resolved when the thread completes.

### [`src/lib.rs`](#)

```rust
use deno_bindgen::deno_bindgen;
use std::{
thread,
time::Duration,
};

#[deno_bindgen(nonblocking)]
pub fn sleep(ms: u32) {
thread::sleep(Duration::from_millis(ms as u64));
}
```

### [`mod.ts`](#)

```ts
import { sleep } from "bindings/bindings.ts";

await sleep(100);
```

### [`Cargo.toml`](#)

```toml
[package]
name = "nonblocking_sleep"
version = "0.1.0"
edition = "2018"

[lib]
crate-type = ["cdylib"]

[dependencies]
deno_bindgen = "0.7.0"
42 changes: 42 additions & 0 deletions docs/src/examples/structs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Working with `struct`

The macro is capable of generating TypeScript definition and glue code for Rust structs. JS objects are serialized to JSON and converted to a struct.

### [`src/lib.rs`](#)

```rust
use deno_bindgen::deno_bindgen;

#[deno_bindgen]
pub struct Input {
a: i32,
b: i32,
}

#[deno_bindgen]
fn add(input: Input) -> i32 {
input.a + input.b
}
```

### [`mod.ts`](#)

```ts
import { add } from "./bindings/bindings.ts";

add({ a: 1, b: 2 }); // 3
```

### [`Cargo.toml`](#)

```toml
[package]
name = "add_object"
version = "0.1.0"
edition = "2018"

[lib]
crate-type = ["cdylib"]

[dependencies]
deno_bindgen = "0.7.0"
25 changes: 25 additions & 0 deletions docs/src/install.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Installation

* Install Rust using `rustup` and Deno.
* Install `deno_bindgen` CLI:

```
deno install -Afq -n deno_bindgen https://deno.land/x/deno_bindgen/cli.ts
```

* Add the following dependencies to your crate.

```toml
[dependencies]
deno_bindgen = "0.7.0"
# (Optional): only when you are using `struct` and `enum`s.
serde = { version = "1", features = ["derive"] }
```

* Change your `crate-type` to `cdylib` and set your package name as well.

```toml
[lib]
name = "my_lib"
crate-type = ["cdylib"]
```
Loading