Merge pull request #290 from napi-rs/remove-bindgen
refactor(napi-sys): remove bindgen
This commit is contained in:
commit
32c7efeee5
39 changed files with 1428 additions and 597 deletions
|
@ -7,7 +7,7 @@ task:
|
||||||
DEBUG: 'napi:*'
|
DEBUG: 'napi:*'
|
||||||
setup_script:
|
setup_script:
|
||||||
- pkg update
|
- pkg update
|
||||||
- pkg install -y -f curl node yarn npm libnghttp2 llvm
|
- pkg install -y -f curl node yarn npm libnghttp2
|
||||||
- curl https://sh.rustup.rs -sSf --output rustup.sh
|
- curl https://sh.rustup.rs -sSf --output rustup.sh
|
||||||
- sh rustup.sh -y --profile minimal --default-toolchain stable
|
- sh rustup.sh -y --profile minimal --default-toolchain stable
|
||||||
- . $HOME/.cargo/env
|
- . $HOME/.cargo/env
|
||||||
|
|
3
.github/workflows/bench.yaml
vendored
3
.github/workflows/bench.yaml
vendored
|
@ -18,9 +18,10 @@ jobs:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Setup node
|
- name: Setup node
|
||||||
uses: actions/setup-node@v1
|
uses: actions/setup-node@v2-beta
|
||||||
with:
|
with:
|
||||||
node-version: 14
|
node-version: 14
|
||||||
|
check-latest: true
|
||||||
|
|
||||||
- name: Install
|
- name: Install
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
|
|
5
.github/workflows/lint.yaml
vendored
5
.github/workflows/lint.yaml
vendored
|
@ -14,9 +14,10 @@ jobs:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Setup node
|
- name: Setup node
|
||||||
uses: actions/setup-node@v1
|
uses: actions/setup-node@v2-beta
|
||||||
with:
|
with:
|
||||||
node-version: 12
|
node-version: 14
|
||||||
|
check-latest: true
|
||||||
|
|
||||||
- name: Install
|
- name: Install
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
|
|
3
.github/workflows/linux-aarch64.yaml
vendored
3
.github/workflows/linux-aarch64.yaml
vendored
|
@ -21,9 +21,10 @@ jobs:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Setup node
|
- name: Setup node
|
||||||
uses: actions/setup-node@v1
|
uses: actions/setup-node@v2-beta
|
||||||
with:
|
with:
|
||||||
node-version: 14
|
node-version: 14
|
||||||
|
check-latest: true
|
||||||
|
|
||||||
- name: Install
|
- name: Install
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
|
|
4
.github/workflows/linux-musl.yaml
vendored
4
.github/workflows/linux-musl.yaml
vendored
|
@ -42,10 +42,6 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
docker run --rm -v $(pwd)/.cargo:/root/.cargo -v $(pwd):/napi-rs -w /napi-rs builder cargo check -vvv
|
docker run --rm -v $(pwd)/.cargo:/root/.cargo -v $(pwd):/napi-rs -w /napi-rs builder cargo check -vvv
|
||||||
|
|
||||||
- name: Run tests
|
|
||||||
run: |
|
|
||||||
docker run --rm -v $(pwd)/.cargo:/root/.cargo -v $(pwd):/napi-rs -w /napi-rs builder cargo test -p napi-sys --lib -- --nocapture
|
|
||||||
|
|
||||||
- name: Unit test
|
- name: Unit test
|
||||||
run: |
|
run: |
|
||||||
docker run --rm -v $(pwd)/.cargo:/root/.cargo -v $(pwd):/napi-rs -w /napi-rs builder sh -c "yarn build:test && yarn test"
|
docker run --rm -v $(pwd)/.cargo:/root/.cargo -v $(pwd):/napi-rs -w /napi-rs builder sh -c "yarn build:test && yarn test"
|
||||||
|
|
9
.github/workflows/napi3.yaml
vendored
9
.github/workflows/napi3.yaml
vendored
|
@ -69,16 +69,9 @@ jobs:
|
||||||
command: check
|
command: check
|
||||||
args: --all --bins --examples --tests -vvv
|
args: --all --bins --examples --tests -vvv
|
||||||
|
|
||||||
- name: Tests
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
timeout-minutes: 5
|
|
||||||
with:
|
|
||||||
command: test
|
|
||||||
args: -p napi-sys --lib -- --nocapture
|
|
||||||
|
|
||||||
- name: Unit tests
|
- name: Unit tests
|
||||||
run: |
|
run: |
|
||||||
yarn --cwd ./test_module --ignore-engines build
|
yarn --cwd ./test_module --ignore-engines build-napi3
|
||||||
yarn --ignore-engines test
|
yarn --ignore-engines test
|
||||||
env:
|
env:
|
||||||
RUST_BACKTRACE: 1
|
RUST_BACKTRACE: 1
|
||||||
|
|
22
.github/workflows/test.yaml
vendored
22
.github/workflows/test.yaml
vendored
|
@ -13,7 +13,7 @@ jobs:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
node: ['10', '12', '14']
|
node: ['10', '12', '14', '15']
|
||||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
|
|
||||||
name: stable - ${{ matrix.os }} - node@${{ matrix.node }}
|
name: stable - ${{ matrix.os }} - node@${{ matrix.node }}
|
||||||
|
@ -23,19 +23,10 @@ jobs:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Setup node
|
- name: Setup node
|
||||||
uses: actions/setup-node@v1
|
uses: actions/setup-node@v2-beta
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node }}
|
node-version: ${{ matrix.node }}
|
||||||
|
check-latest: true
|
||||||
- name: Install llvm
|
|
||||||
if: matrix.os == 'windows-latest'
|
|
||||||
run: choco install -y llvm
|
|
||||||
|
|
||||||
- name: Set llvm path
|
|
||||||
if: matrix.os == 'windows-latest'
|
|
||||||
uses: allenevans/set-env@v1.1.0
|
|
||||||
with:
|
|
||||||
LIBCLANG_PATH: 'C:\Program Files\LLVM\bin'
|
|
||||||
|
|
||||||
- name: Install
|
- name: Install
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
|
@ -81,13 +72,6 @@ jobs:
|
||||||
command: check
|
command: check
|
||||||
args: --all --bins --examples --tests -vvv
|
args: --all --bins --examples --tests -vvv
|
||||||
|
|
||||||
- name: Tests
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
timeout-minutes: 5
|
|
||||||
with:
|
|
||||||
command: test
|
|
||||||
args: -p napi-sys --lib -- --nocapture
|
|
||||||
|
|
||||||
- name: Unit tests
|
- name: Unit tests
|
||||||
run: |
|
run: |
|
||||||
yarn build:test
|
yarn build:test
|
||||||
|
|
42
.github/workflows/windows-i686.yml
vendored
42
.github/workflows/windows-i686.yml
vendored
|
@ -17,17 +17,27 @@ jobs:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Setup node
|
- name: Setup node
|
||||||
uses: actions/setup-node@v1
|
run: choco install nodejs-lts --x86 -y --force
|
||||||
with:
|
|
||||||
node-version: 14
|
|
||||||
|
|
||||||
- name: Install llvm
|
- name: Set 32bit NodeJS path
|
||||||
run: choco install -y llvm
|
run: |
|
||||||
|
echo "C:\\Program Files (x86)\\nodejs" >> $GITHUB_PATH
|
||||||
- name: Set llvm path
|
|
||||||
run: echo "LIBCLANG_PATH=C:\\Program Files\\LLVM\\bin" >> $GITHUB_ENV
|
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
|
- name: Cache NPM dependencies
|
||||||
|
uses: actions/cache@v1
|
||||||
|
with:
|
||||||
|
path: node_modules
|
||||||
|
key: npm-cache-windows-i686-node@lts-${{ hashFiles('yarn.lock') }}
|
||||||
|
restore-keys: |
|
||||||
|
npm-cache-
|
||||||
|
|
||||||
|
- name: 'Install dependencies'
|
||||||
|
run: yarn install --frozen-lockfile --registry https://registry.npmjs.org
|
||||||
|
|
||||||
|
- name: 'Build TypeScript'
|
||||||
|
run: yarn build
|
||||||
|
|
||||||
- name: Install
|
- name: Install
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
|
@ -47,13 +57,13 @@ jobs:
|
||||||
uses: actions/cache@v1
|
uses: actions/cache@v1
|
||||||
with:
|
with:
|
||||||
path: ~/.cargo/registry
|
path: ~/.cargo/registry
|
||||||
key: stable-${{ matrix.os }}-node@${{ matrix.node }}-cargo-registry-trimmed-${{ hashFiles('**/Cargo.lock') }}
|
key: stable-windows-i686-node@lts-cargo-registry-trimmed-${{ hashFiles('**/Cargo.lock') }}
|
||||||
|
|
||||||
- name: Cache cargo index
|
- name: Cache cargo index
|
||||||
uses: actions/cache@v1
|
uses: actions/cache@v1
|
||||||
with:
|
with:
|
||||||
path: ~/.cargo/git
|
path: ~/.cargo/git
|
||||||
key: stable-${{ matrix.os }}gnu-node@${{ matrix.node }}-cargo-index-trimmed-${{ hashFiles('**/Cargo.lock') }}
|
key: stable-windows-i686-node@lts-cargo-index-trimmed-${{ hashFiles('**/Cargo.lock') }}
|
||||||
|
|
||||||
- name: Check build
|
- name: Check build
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
|
@ -61,12 +71,12 @@ jobs:
|
||||||
command: check
|
command: check
|
||||||
args: --all --bins --examples --tests --target i686-pc-windows-msvc -vvv
|
args: --all --bins --examples --tests --target i686-pc-windows-msvc -vvv
|
||||||
|
|
||||||
- name: Tests
|
- name: Build Tests
|
||||||
uses: actions-rs/cargo@v1
|
run: |
|
||||||
timeout-minutes: 5
|
yarn --cwd ./test_module build-i686
|
||||||
with:
|
yarn test
|
||||||
command: test
|
env:
|
||||||
args: -p napi-sys --lib --target i686-pc-windows-msvc -- --nocapture
|
RUST_BACKTRACE: 1
|
||||||
|
|
||||||
- name: Clear the cargo caches
|
- name: Clear the cargo caches
|
||||||
run: |
|
run: |
|
||||||
|
|
|
@ -28,9 +28,9 @@ A minimal library for building compiled `NodeJS` add-ons in `Rust`.
|
||||||
|
|
||||||
## NodeJS
|
## NodeJS
|
||||||
|
|
||||||
| Node10 | Node 12 | Node14 |
|
| Node10 | Node 12 | Node14 | Node15 |
|
||||||
| ------ | ------- | ------ |
|
| ------ | ------- | ------ | ------ |
|
||||||
| ✓ | ✓ | ✓ |
|
| ✓ | ✓ | ✓ | ✓ |
|
||||||
|
|
||||||
This library depends on N-API and requires `Node@8.9` or later.
|
This library depends on N-API and requires `Node@8.9` or later.
|
||||||
|
|
||||||
|
|
|
@ -8,14 +8,8 @@ version = "0.1.0"
|
||||||
crate-type = ["cdylib"]
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
futures = "0.3"
|
napi = {path = "../napi"}
|
||||||
napi = {path = "../napi", features = ["libuv", "tokio_rt", "serde-json", "latin1"]}
|
|
||||||
napi-derive = {path = "../napi-derive"}
|
napi-derive = {path = "../napi-derive"}
|
||||||
serde = "1"
|
|
||||||
serde_bytes = "0.11"
|
|
||||||
serde_derive = "1"
|
|
||||||
serde_json = "1"
|
|
||||||
tokio = {version = "0.2", features = ["default", "fs"]}
|
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
napi-build = {path = "../build"}
|
napi-build = {path = "../build"}
|
||||||
|
|
|
@ -1,40 +1,11 @@
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(windows)] {
|
if #[cfg(windows)] {
|
||||||
mod windows;
|
mod windows;
|
||||||
pub use windows::setup;
|
pub use windows::setup;
|
||||||
} else if #[cfg(target_os = "macos")] {
|
} else if #[cfg(target_os = "macos")] {
|
||||||
mod macos;
|
mod macos;
|
||||||
pub use macos::setup;
|
pub use macos::setup;
|
||||||
} else {
|
|
||||||
pub fn setup() {
|
|
||||||
setup_napi_feature();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
use std::process::Command;
|
|
||||||
|
|
||||||
pub fn setup_napi_feature() {
|
|
||||||
let napi_version = String::from_utf8(
|
|
||||||
Command::new("node")
|
|
||||||
.args(&["-e", "console.log(process.versions.napi)"])
|
|
||||||
.output()
|
|
||||||
.unwrap()
|
|
||||||
.stdout,
|
|
||||||
)
|
|
||||||
.expect("Get NAPI version failed");
|
|
||||||
|
|
||||||
let napi_version_number = napi_version.trim().parse::<u32>().unwrap();
|
|
||||||
|
|
||||||
if napi_version_number < 2 {
|
|
||||||
panic!("current napi version is too low");
|
|
||||||
}
|
|
||||||
|
|
||||||
if napi_version_number == 2 {
|
|
||||||
println!("cargo:rustc-cfg=napi{}", napi_version_number);
|
|
||||||
} else {
|
} else {
|
||||||
for version in 2..(napi_version_number + 1) {
|
pub fn setup() { }
|
||||||
println!("cargo:rustc-cfg=napi{}", version);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
use crate::*;
|
|
||||||
|
|
||||||
pub fn setup() {
|
pub fn setup() {
|
||||||
println!("cargo:rustc-cdylib-link-arg=-Wl");
|
println!("cargo:rustc-cdylib-link-arg=-Wl");
|
||||||
println!("cargo:rustc-cdylib-link-arg=-undefined");
|
println!("cargo:rustc-cdylib-link-arg=-undefined");
|
||||||
println!("cargo:rustc-cdylib-link-arg=dynamic_lookup");
|
println!("cargo:rustc-cdylib-link-arg=dynamic_lookup");
|
||||||
setup_napi_feature();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use crate::*;
|
|
||||||
use std::collections::hash_map::DefaultHasher;
|
use std::collections::hash_map::DefaultHasher;
|
||||||
use std::fs::{metadata, write};
|
use std::fs::{metadata, write};
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use std::process::Command;
|
||||||
|
|
||||||
fn get_node_version() -> std::io::Result<String> {
|
fn get_node_version() -> std::io::Result<String> {
|
||||||
let output = Command::new("node").arg("-v").output()?;
|
let output = Command::new("node").arg("-v").output()?;
|
||||||
|
@ -51,16 +51,17 @@ pub fn setup() {
|
||||||
// See https://doc.rust-lang.org/reference/conditional-compilation.html#target_arch for rust env values.
|
// See https://doc.rust-lang.org/reference/conditional-compilation.html#target_arch for rust env values.
|
||||||
// Nodejs appears to follow `process.arch`.
|
// Nodejs appears to follow `process.arch`.
|
||||||
// See https://nodejs.org/docs/latest/api/process.html#process_process_arch for npm env values.
|
// See https://nodejs.org/docs/latest/api/process.html#process_process_arch for npm env values.
|
||||||
|
// For windows, we only support `['ia32', 'x64', 'arm64']`
|
||||||
|
// https://github.com/nodejs/node-gyp/blob/master/lib/install.js#L301
|
||||||
let arch = std::env::var("CARGO_CFG_TARGET_ARCH")
|
let arch = std::env::var("CARGO_CFG_TARGET_ARCH")
|
||||||
.map(|arch| match arch.as_str() {
|
.map(|arch| match arch.as_str() {
|
||||||
"x86" => "x86", // TODO: x86 appears to also be called ia32 in npm_config_arch sometimes. What is the right value?
|
"x86" => "x86",
|
||||||
"x86_64" => "x64",
|
"x86_64" => "x64",
|
||||||
"mips" => "mips",
|
// https://github.com/nodejs/node/issues/25998
|
||||||
"powerpc" => "ppc",
|
// actually not supported for now
|
||||||
"powerpc64" => "ppc64",
|
// because we can not get `node.lib` file for `aarch64` device
|
||||||
"arm" => "arm",
|
|
||||||
"aarch64" => "arm64",
|
"aarch64" => "arm64",
|
||||||
arch => panic!("Unknown Architecture: {}", arch),
|
arch => panic!("Unsupported CPU Architecture: {}", arch),
|
||||||
})
|
})
|
||||||
.expect("Failed to determine target arch");
|
.expect("Failed to determine target arch");
|
||||||
|
|
||||||
|
@ -106,6 +107,4 @@ pub fn setup() {
|
||||||
);
|
);
|
||||||
println!("cargo:rustc-cdylib-link-arg=delayimp.lib");
|
println!("cargo:rustc-cdylib-link-arg=delayimp.lib");
|
||||||
println!("cargo:rustc-cdylib-link-arg=/DELAYLOAD:node.exe");
|
println!("cargo:rustc-cdylib-link-arg=/DELAYLOAD:node.exe");
|
||||||
|
|
||||||
setup_napi_feature();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,15 @@ repository = "https://github.com/napi-rs/napi-rs"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
default = ["napi3"] # for most NodeJS users
|
||||||
latin1 = ["encoding_rs"]
|
latin1 = ["encoding_rs"]
|
||||||
libuv = ["futures"]
|
napi1 = []
|
||||||
|
napi2 = ["napi1"]
|
||||||
|
napi3 = ["napi2", "napi-sys/napi3"]
|
||||||
|
napi4 = ["napi3", "napi-sys/napi4"]
|
||||||
|
napi5 = ["napi4", "napi-sys/napi5"]
|
||||||
|
napi6 = ["napi5", "napi-sys/napi6"]
|
||||||
|
napi7 = ["napi6", "napi-sys/napi7"]
|
||||||
serde-json = ["serde", "serde_json"]
|
serde-json = ["serde", "serde_json"]
|
||||||
tokio_rt = ["futures", "tokio", "once_cell"]
|
tokio_rt = ["futures", "tokio", "once_cell"]
|
||||||
|
|
||||||
|
@ -51,4 +58,3 @@ napi-build = {version = "0.2", path = "../build"}
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
all-features = true
|
all-features = true
|
||||||
rustc-args = ["--cfg", "napidocsrs"]
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
fn main() {
|
|
||||||
napi_build::setup_napi_feature();
|
|
||||||
}
|
|
|
@ -5,30 +5,29 @@ use std::mem;
|
||||||
use std::os::raw::{c_char, c_void};
|
use std::os::raw::{c_char, c_void};
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
use super::cleanup_env::{CleanupEnvHook, CleanupEnvHookData};
|
|
||||||
use crate::async_work::{self, AsyncWorkPromise};
|
use crate::async_work::{self, AsyncWorkPromise};
|
||||||
use crate::error::check_status;
|
use crate::error::check_status;
|
||||||
use crate::js_values::*;
|
use crate::js_values::*;
|
||||||
use crate::task::Task;
|
use crate::task::Task;
|
||||||
use crate::{sys, Error, NodeVersion, Result, Status};
|
use crate::{sys, Error, NodeVersion, Result, Status};
|
||||||
|
|
||||||
|
#[cfg(feature = "napi3")]
|
||||||
|
use super::cleanup_env::{CleanupEnvHook, CleanupEnvHookData};
|
||||||
#[cfg(all(feature = "serde-json"))]
|
#[cfg(all(feature = "serde-json"))]
|
||||||
use crate::js_values::{De, Ser};
|
use crate::js_values::{De, Ser};
|
||||||
#[cfg(all(any(feature = "libuv", feature = "tokio_rt"), napi4))]
|
#[cfg(all(feature = "tokio_rt", feature = "napi4"))]
|
||||||
use crate::promise;
|
use crate::promise;
|
||||||
#[cfg(napi4)]
|
#[cfg(feature = "napi4")]
|
||||||
use crate::threadsafe_function::{ThreadSafeCallContext, ThreadsafeFunction};
|
use crate::threadsafe_function::{ThreadSafeCallContext, ThreadsafeFunction};
|
||||||
#[cfg(all(feature = "tokio_rt", napi4))]
|
#[cfg(all(feature = "tokio_rt", feature = "napi4"))]
|
||||||
use crate::tokio_rt::{get_tokio_sender, Message};
|
use crate::tokio_rt::{get_tokio_sender, Message};
|
||||||
#[cfg(all(feature = "libuv", napi4))]
|
|
||||||
use crate::uv;
|
|
||||||
#[cfg(all(feature = "serde-json"))]
|
#[cfg(all(feature = "serde-json"))]
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
#[cfg(all(feature = "serde-json"))]
|
#[cfg(all(feature = "serde-json"))]
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
#[cfg(all(feature = "libuv", napi4))]
|
#[cfg(all(feature = "tokio_rt", feature = "napi4"))]
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
#[cfg(all(feature = "tokio_rt", napi4))]
|
#[cfg(all(feature = "tokio_rt", feature = "napi4"))]
|
||||||
use tokio::sync::mpsc::error::TrySendError;
|
use tokio::sync::mpsc::error::TrySendError;
|
||||||
|
|
||||||
pub type Callback = extern "C" fn(sys::napi_env, sys::napi_callback_info) -> sys::napi_value;
|
pub type Callback = extern "C" fn(sys::napi_env, sys::napi_callback_info) -> sys::napi_value;
|
||||||
|
@ -90,7 +89,7 @@ impl Env {
|
||||||
Ok(JsNumber::from_raw_unchecked(self.0, raw_value))
|
Ok(JsNumber::from_raw_unchecked(self.0, raw_value))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
/// [n_api_napi_create_bigint_int64](https://nodejs.org/api/n-api.html#n_api_napi_create_bigint_int64)
|
/// [n_api_napi_create_bigint_int64](https://nodejs.org/api/n-api.html#n_api_napi_create_bigint_int64)
|
||||||
pub fn create_bigint_from_i64(&self, value: i64) -> Result<JsBigint> {
|
pub fn create_bigint_from_i64(&self, value: i64) -> Result<JsBigint> {
|
||||||
let mut raw_value = ptr::null_mut();
|
let mut raw_value = ptr::null_mut();
|
||||||
|
@ -98,14 +97,14 @@ impl Env {
|
||||||
Ok(JsBigint::from_raw_unchecked(self.0, raw_value, 1))
|
Ok(JsBigint::from_raw_unchecked(self.0, raw_value, 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
pub fn create_bigint_from_u64(&self, value: u64) -> Result<JsBigint> {
|
pub fn create_bigint_from_u64(&self, value: u64) -> Result<JsBigint> {
|
||||||
let mut raw_value = ptr::null_mut();
|
let mut raw_value = ptr::null_mut();
|
||||||
check_status(unsafe { sys::napi_create_bigint_uint64(self.0, value, &mut raw_value) })?;
|
check_status(unsafe { sys::napi_create_bigint_uint64(self.0, value, &mut raw_value) })?;
|
||||||
Ok(JsBigint::from_raw_unchecked(self.0, raw_value, 1))
|
Ok(JsBigint::from_raw_unchecked(self.0, raw_value, 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
pub fn create_bigint_from_i128(&self, value: i128) -> Result<JsBigint> {
|
pub fn create_bigint_from_i128(&self, value: i128) -> Result<JsBigint> {
|
||||||
let mut raw_value = ptr::null_mut();
|
let mut raw_value = ptr::null_mut();
|
||||||
let sign_bit = if value > 0 { 0 } else { 1 };
|
let sign_bit = if value > 0 { 0 } else { 1 };
|
||||||
|
@ -116,7 +115,7 @@ impl Env {
|
||||||
Ok(JsBigint::from_raw_unchecked(self.0, raw_value, 1))
|
Ok(JsBigint::from_raw_unchecked(self.0, raw_value, 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
pub fn create_bigint_from_u128(&self, value: u128) -> Result<JsBigint> {
|
pub fn create_bigint_from_u128(&self, value: u128) -> Result<JsBigint> {
|
||||||
let mut raw_value = ptr::null_mut();
|
let mut raw_value = ptr::null_mut();
|
||||||
let words = &value as *const u128 as *const u64;
|
let words = &value as *const u128 as *const u64;
|
||||||
|
@ -124,7 +123,7 @@ impl Env {
|
||||||
Ok(JsBigint::from_raw_unchecked(self.0, raw_value, 1))
|
Ok(JsBigint::from_raw_unchecked(self.0, raw_value, 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
/// [n_api_napi_create_bigint_words](https://nodejs.org/api/n-api.html#n_api_napi_create_bigint_words)
|
/// [n_api_napi_create_bigint_words](https://nodejs.org/api/n-api.html#n_api_napi_create_bigint_words)
|
||||||
/// The resulting BigInt will be negative when sign_bit is true.
|
/// The resulting BigInt will be negative when sign_bit is true.
|
||||||
pub fn create_bigint_from_words(&self, sign_bit: bool, words: Vec<u64>) -> Result<JsBigint> {
|
pub fn create_bigint_from_words(&self, sign_bit: bool, words: Vec<u64>) -> Result<JsBigint> {
|
||||||
|
@ -549,14 +548,14 @@ impl Env {
|
||||||
.map_err(|e| Error::new(Status::InvalidArg, format!("{}", e)))
|
.map_err(|e| Error::new(Status::InvalidArg, format!("{}", e)))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(napi2)]
|
#[cfg(feature = "napi2")]
|
||||||
pub fn get_uv_event_loop(&self) -> Result<*mut sys::uv_loop_s> {
|
pub fn get_uv_event_loop(&self) -> Result<*mut sys::uv_loop_s> {
|
||||||
let mut uv_loop: *mut sys::uv_loop_s = ptr::null_mut();
|
let mut uv_loop: *mut sys::uv_loop_s = ptr::null_mut();
|
||||||
check_status(unsafe { sys::napi_get_uv_event_loop(self.0, &mut uv_loop) })?;
|
check_status(unsafe { sys::napi_get_uv_event_loop(self.0, &mut uv_loop) })?;
|
||||||
Ok(uv_loop)
|
Ok(uv_loop)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(napi3)]
|
#[cfg(feature = "napi3")]
|
||||||
pub fn add_env_cleanup_hook<T, F>(
|
pub fn add_env_cleanup_hook<T, F>(
|
||||||
&mut self,
|
&mut self,
|
||||||
cleanup_data: T,
|
cleanup_data: T,
|
||||||
|
@ -581,7 +580,7 @@ impl Env {
|
||||||
Ok(CleanupEnvHook(hook_ref))
|
Ok(CleanupEnvHook(hook_ref))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(napi3)]
|
#[cfg(feature = "napi3")]
|
||||||
pub fn remove_env_cleanup_hook<T>(&mut self, hook: CleanupEnvHook<T>) -> Result<()>
|
pub fn remove_env_cleanup_hook<T>(&mut self, hook: CleanupEnvHook<T>) -> Result<()>
|
||||||
where
|
where
|
||||||
T: 'static,
|
T: 'static,
|
||||||
|
@ -591,7 +590,7 @@ impl Env {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(napi4)]
|
#[cfg(feature = "napi4")]
|
||||||
pub fn create_threadsafe_function<
|
pub fn create_threadsafe_function<
|
||||||
T: Send,
|
T: Send,
|
||||||
V: NapiValue,
|
V: NapiValue,
|
||||||
|
@ -605,31 +604,7 @@ impl Env {
|
||||||
ThreadsafeFunction::create(self.0, func, max_queue_size, callback)
|
ThreadsafeFunction::create(self.0, func, max_queue_size, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(feature = "libuv", napi4))]
|
#[cfg(all(feature = "tokio_rt", feature = "napi4"))]
|
||||||
pub fn execute<
|
|
||||||
T: 'static + Send,
|
|
||||||
V: 'static + NapiValue,
|
|
||||||
F: 'static + Future<Output = Result<T>>,
|
|
||||||
R: 'static + Send + Sync + FnOnce(&mut Env, T) -> Result<V>,
|
|
||||||
>(
|
|
||||||
&self,
|
|
||||||
deferred: F,
|
|
||||||
resolver: R,
|
|
||||||
) -> Result<JsObject> {
|
|
||||||
let mut raw_promise = ptr::null_mut();
|
|
||||||
let mut raw_deferred = ptr::null_mut();
|
|
||||||
|
|
||||||
check_status(unsafe { sys::napi_create_promise(self.0, &mut raw_deferred, &mut raw_promise) })?;
|
|
||||||
|
|
||||||
let event_loop = self.get_uv_event_loop()?;
|
|
||||||
let future_promise = promise::FuturePromise::create(self.0, raw_deferred, Box::from(resolver))?;
|
|
||||||
let future_to_execute = promise::resolve_from_future(future_promise.start()?, deferred);
|
|
||||||
uv::execute(event_loop, Box::pin(future_to_execute))?;
|
|
||||||
|
|
||||||
Ok(JsObject::from_raw_unchecked(self.0, raw_promise))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(all(feature = "tokio_rt", napi4))]
|
|
||||||
pub fn execute_tokio_future<
|
pub fn execute_tokio_future<
|
||||||
T: 'static + Send,
|
T: 'static + Send,
|
||||||
V: 'static + NapiValue,
|
V: 'static + NapiValue,
|
||||||
|
@ -664,7 +639,7 @@ impl Env {
|
||||||
Ok(JsObject::from_raw_unchecked(self.0, raw_promise))
|
Ok(JsObject::from_raw_unchecked(self.0, raw_promise))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(napi5)]
|
#[cfg(feature = "napi5")]
|
||||||
pub fn create_date(&self, time: f64) -> Result<JsDate> {
|
pub fn create_date(&self, time: f64) -> Result<JsDate> {
|
||||||
let mut js_value = ptr::null_mut();
|
let mut js_value = ptr::null_mut();
|
||||||
check_status(unsafe { sys::napi_create_date(self.0, time, &mut js_value) })?;
|
check_status(unsafe { sys::napi_create_date(self.0, time, &mut js_value) })?;
|
||||||
|
@ -738,6 +713,11 @@ impl Env {
|
||||||
let version = unsafe { *result };
|
let version = unsafe { *result };
|
||||||
version.try_into()
|
version.try_into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// get raw env ptr
|
||||||
|
pub fn raw(&self) -> sys::napi_env {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn drop_buffer(env: sys::napi_env, finalize_data: *mut c_void, len: *mut c_void) {
|
unsafe extern "C" fn drop_buffer(env: sys::napi_env, finalize_data: *mut c_void, len: *mut c_void) {
|
||||||
|
@ -759,6 +739,7 @@ unsafe extern "C" fn raw_finalize<T>(
|
||||||
Box::from_raw(tagged_object);
|
Box::from_raw(tagged_object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "napi3")]
|
||||||
unsafe extern "C" fn cleanup_env<T: 'static>(hook_data: *mut c_void) {
|
unsafe extern "C" fn cleanup_env<T: 'static>(hook_data: *mut c_void) {
|
||||||
let cleanup_env_hook = Box::from_raw(hook_data as *mut CleanupEnvHookData<T>);
|
let cleanup_env_hook = Box::from_raw(hook_data as *mut CleanupEnvHookData<T>);
|
||||||
(cleanup_env_hook.hook)(cleanup_env_hook.data);
|
(cleanup_env_hook.hook)(cleanup_env_hook.data);
|
||||||
|
|
|
@ -7,7 +7,7 @@ use std::ptr;
|
||||||
|
|
||||||
use super::{Value, ValueType};
|
use super::{Value, ValueType};
|
||||||
use crate::error::check_status;
|
use crate::error::check_status;
|
||||||
use crate::{sys, Error, JsUnknown, NapiValue, Ref, Result, Status};
|
use crate::{sys, Error, JsUnknown, NapiValue, Ref, Result};
|
||||||
|
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -44,6 +44,7 @@ pub struct JsDataViewValue {
|
||||||
pub length: u64,
|
pub length: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(u8)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum TypedArrayType {
|
pub enum TypedArrayType {
|
||||||
Int8,
|
Int8,
|
||||||
|
@ -55,9 +56,9 @@ pub enum TypedArrayType {
|
||||||
Uint32,
|
Uint32,
|
||||||
Float32,
|
Float32,
|
||||||
Float64,
|
Float64,
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
BigInt64,
|
BigInt64,
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
BigUint64,
|
BigUint64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,11 +76,10 @@ impl TryFrom<sys::napi_typedarray_type> for TypedArrayType {
|
||||||
sys::napi_typedarray_type::napi_uint32_array => Ok(Self::Uint32),
|
sys::napi_typedarray_type::napi_uint32_array => Ok(Self::Uint32),
|
||||||
sys::napi_typedarray_type::napi_float32_array => Ok(Self::Float32),
|
sys::napi_typedarray_type::napi_float32_array => Ok(Self::Float32),
|
||||||
sys::napi_typedarray_type::napi_float64_array => Ok(Self::Float64),
|
sys::napi_typedarray_type::napi_float64_array => Ok(Self::Float64),
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
sys::napi_typedarray_type::napi_bigint64_array => Ok(Self::BigInt64),
|
sys::napi_typedarray_type::napi_bigint64_array => Ok(Self::BigInt64),
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
sys::napi_typedarray_type::napi_biguint64_array => Ok(Self::BigUint64),
|
sys::napi_typedarray_type::napi_biguint64_array => Ok(Self::BigUint64),
|
||||||
_ => Err(Error::from_status(Status::Unknown)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,21 +96,21 @@ impl From<TypedArrayType> for sys::napi_typedarray_type {
|
||||||
TypedArrayType::Uint32 => sys::napi_typedarray_type::napi_uint32_array,
|
TypedArrayType::Uint32 => sys::napi_typedarray_type::napi_uint32_array,
|
||||||
TypedArrayType::Float32 => sys::napi_typedarray_type::napi_float32_array,
|
TypedArrayType::Float32 => sys::napi_typedarray_type::napi_float32_array,
|
||||||
TypedArrayType::Float64 => sys::napi_typedarray_type::napi_float64_array,
|
TypedArrayType::Float64 => sys::napi_typedarray_type::napi_float64_array,
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
TypedArrayType::BigInt64 => sys::napi_typedarray_type::napi_bigint64_array,
|
TypedArrayType::BigInt64 => sys::napi_typedarray_type::napi_bigint64_array,
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
TypedArrayType::BigUint64 => sys::napi_typedarray_type::napi_biguint64_array,
|
TypedArrayType::BigUint64 => sys::napi_typedarray_type::napi_biguint64_array,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl JsArrayBuffer {
|
impl JsArrayBuffer {
|
||||||
#[cfg(napi7)]
|
#[cfg(feature = "napi7")]
|
||||||
pub fn detach(self) -> Result<()> {
|
pub fn detach(self) -> Result<()> {
|
||||||
check_status(unsafe { sys::napi_detach_arraybuffer(self.0.env, self.0.value) })
|
check_status(unsafe { sys::napi_detach_arraybuffer(self.0.env, self.0.value) })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(napi7)]
|
#[cfg(feature = "napi7")]
|
||||||
pub fn is_detached(&self) -> Result<bool> {
|
pub fn is_detached(&self) -> Result<bool> {
|
||||||
let mut is_detached = false;
|
let mut is_detached = false;
|
||||||
check_status(unsafe {
|
check_status(unsafe {
|
||||||
|
|
|
@ -71,7 +71,7 @@ impl JsBigint {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(napi5)]
|
#[cfg(feature = "napi5")]
|
||||||
pub fn is_date(&self) -> Result<bool> {
|
pub fn is_date(&self) -> Result<bool> {
|
||||||
let mut is_date = true;
|
let mut is_date = true;
|
||||||
check_status(unsafe { sys::napi_is_date(self.raw.env, self.raw.value, &mut is_date) })?;
|
check_status(unsafe { sys::napi_is_date(self.raw.env, self.raw.value, &mut is_date) })?;
|
||||||
|
|
|
@ -4,7 +4,7 @@ use serde::de::Visitor;
|
||||||
use serde::de::{DeserializeSeed, EnumAccess, MapAccess, SeqAccess, Unexpected, VariantAccess};
|
use serde::de::{DeserializeSeed, EnumAccess, MapAccess, SeqAccess, Unexpected, VariantAccess};
|
||||||
|
|
||||||
use super::{type_of, NapiValue, Value, ValueType};
|
use super::{type_of, NapiValue, Value, ValueType};
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
use crate::JsBigint;
|
use crate::JsBigint;
|
||||||
use crate::{
|
use crate::{
|
||||||
Error, JsBoolean, JsBufferValue, JsNumber, JsObject, JsString, JsUnknown, Result, Status,
|
Error, JsBoolean, JsBufferValue, JsNumber, JsObject, JsString, JsUnknown, Result, Status,
|
||||||
|
@ -52,7 +52,7 @@ impl<'x, 'de, 'env> serde::de::Deserializer<'x> for &'de mut De<'env> {
|
||||||
visitor.visit_map(&mut deserializer)
|
visitor.visit_map(&mut deserializer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
ValueType::Bigint => {
|
ValueType::Bigint => {
|
||||||
let mut js_bigint = JsBigint::from_raw(self.0.env, self.0.value)?;
|
let mut js_bigint = JsBigint::from_raw(self.0.env, self.0.value)?;
|
||||||
let (signed, v, _loss) = js_bigint.get_u128()?;
|
let (signed, v, _loss) = js_bigint.get_u128()?;
|
||||||
|
|
|
@ -11,11 +11,11 @@ mod de;
|
||||||
mod ser;
|
mod ser;
|
||||||
|
|
||||||
mod arraybuffer;
|
mod arraybuffer;
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
mod bigint;
|
mod bigint;
|
||||||
mod boolean;
|
mod boolean;
|
||||||
mod buffer;
|
mod buffer;
|
||||||
#[cfg(napi5)]
|
#[cfg(feature = "napi5")]
|
||||||
mod date;
|
mod date;
|
||||||
mod either;
|
mod either;
|
||||||
mod escapable_handle_scope;
|
mod escapable_handle_scope;
|
||||||
|
@ -32,11 +32,11 @@ mod value_ref;
|
||||||
mod value_type;
|
mod value_type;
|
||||||
|
|
||||||
pub use arraybuffer::*;
|
pub use arraybuffer::*;
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
pub use bigint::JsBigint;
|
pub use bigint::JsBigint;
|
||||||
pub use boolean::JsBoolean;
|
pub use boolean::JsBoolean;
|
||||||
pub use buffer::*;
|
pub use buffer::*;
|
||||||
#[cfg(napi5)]
|
#[cfg(feature = "napi5")]
|
||||||
pub use date::*;
|
pub use date::*;
|
||||||
#[cfg(feature = "serde-json")]
|
#[cfg(feature = "serde-json")]
|
||||||
pub(crate) use de::De;
|
pub(crate) use de::De;
|
||||||
|
@ -78,7 +78,7 @@ pub(crate) fn type_of(env: sys::napi_env, raw_value: sys::napi_value) -> Result<
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut value_type = sys::napi_valuetype::napi_undefined;
|
let mut value_type = sys::napi_valuetype::napi_undefined;
|
||||||
check_status(sys::napi_typeof(env, raw_value, &mut value_type))?;
|
check_status(sys::napi_typeof(env, raw_value, &mut value_type))?;
|
||||||
ValueType::try_from(value_type)
|
Ok(ValueType::from(value_type))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,7 +171,7 @@ macro_rules! impl_js_value_methods {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(napi5)]
|
#[cfg(feature = "napi5")]
|
||||||
pub fn is_date(&self) -> Result<bool> {
|
pub fn is_date(&self) -> Result<bool> {
|
||||||
let mut is_date = true;
|
let mut is_date = true;
|
||||||
check_status(unsafe { sys::napi_is_date(self.0.env, self.0.value, &mut is_date) })?;
|
check_status(unsafe { sys::napi_is_date(self.0.env, self.0.value, &mut is_date) })?;
|
||||||
|
@ -363,7 +363,7 @@ macro_rules! impl_object_methods {
|
||||||
|
|
||||||
/// https://nodejs.org/api/n-api.html#n_api_napi_get_all_property_names
|
/// https://nodejs.org/api/n-api.html#n_api_napi_get_all_property_names
|
||||||
/// return `Array` of property names
|
/// return `Array` of property names
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
pub fn get_all_property_names(
|
pub fn get_all_property_names(
|
||||||
&self,
|
&self,
|
||||||
mode: KeyCollectionMode,
|
mode: KeyCollectionMode,
|
||||||
|
@ -484,7 +484,7 @@ impl_js_value_methods!(JsNumber);
|
||||||
impl_js_value_methods!(JsString);
|
impl_js_value_methods!(JsString);
|
||||||
impl_js_value_methods!(JsObject);
|
impl_js_value_methods!(JsObject);
|
||||||
impl_js_value_methods!(JsGlobal);
|
impl_js_value_methods!(JsGlobal);
|
||||||
#[cfg(napi5)]
|
#[cfg(feature = "napi5")]
|
||||||
impl_js_value_methods!(JsDate);
|
impl_js_value_methods!(JsDate);
|
||||||
impl_js_value_methods!(JsFunction);
|
impl_js_value_methods!(JsFunction);
|
||||||
impl_js_value_methods!(JsExternal);
|
impl_js_value_methods!(JsExternal);
|
||||||
|
@ -511,7 +511,7 @@ impl_napi_value_trait!(JsNumber, Number);
|
||||||
impl_napi_value_trait!(JsString, String);
|
impl_napi_value_trait!(JsString, String);
|
||||||
impl_napi_value_trait!(JsObject, Object);
|
impl_napi_value_trait!(JsObject, Object);
|
||||||
impl_napi_value_trait!(JsGlobal, Object);
|
impl_napi_value_trait!(JsGlobal, Object);
|
||||||
#[cfg(napi5)]
|
#[cfg(feature = "napi5")]
|
||||||
impl_napi_value_trait!(JsDate, Object);
|
impl_napi_value_trait!(JsDate, Object);
|
||||||
impl_napi_value_trait!(JsTimeout, Object);
|
impl_napi_value_trait!(JsTimeout, Object);
|
||||||
impl_napi_value_trait!(JsFunction, Function);
|
impl_napi_value_trait!(JsFunction, Function);
|
||||||
|
@ -535,6 +535,7 @@ impl NapiValue for JsUnknown {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// get raw js value ptr
|
||||||
fn raw(&self) -> sys::napi_value {
|
fn raw(&self) -> sys::napi_value {
|
||||||
self.0.value
|
self.0.value
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,22 @@
|
||||||
use super::Value;
|
use super::Value;
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
use crate::sys;
|
use crate::sys;
|
||||||
use crate::{Error, Result, Status};
|
#[cfg(feature = "napi6")]
|
||||||
|
use crate::{Error, Result};
|
||||||
|
#[cfg(feature = "napi6")]
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct JsObject(pub(crate) Value);
|
pub struct JsObject(pub(crate) Value);
|
||||||
|
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
pub enum KeyCollectionMode {
|
pub enum KeyCollectionMode {
|
||||||
IncludePrototypes,
|
IncludePrototypes,
|
||||||
OwnOnly,
|
OwnOnly,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
impl TryFrom<sys::napi_key_collection_mode> for KeyCollectionMode {
|
impl TryFrom<sys::napi_key_collection_mode> for KeyCollectionMode {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
|
@ -22,12 +24,11 @@ impl TryFrom<sys::napi_key_collection_mode> for KeyCollectionMode {
|
||||||
match value {
|
match value {
|
||||||
sys::napi_key_collection_mode::napi_key_include_prototypes => Ok(Self::IncludePrototypes),
|
sys::napi_key_collection_mode::napi_key_include_prototypes => Ok(Self::IncludePrototypes),
|
||||||
sys::napi_key_collection_mode::napi_key_own_only => Ok(Self::OwnOnly),
|
sys::napi_key_collection_mode::napi_key_own_only => Ok(Self::OwnOnly),
|
||||||
_ => Err(Error::from_status(Status::Unknown)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
impl From<KeyCollectionMode> for sys::napi_key_collection_mode {
|
impl From<KeyCollectionMode> for sys::napi_key_collection_mode {
|
||||||
fn from(value: KeyCollectionMode) -> Self {
|
fn from(value: KeyCollectionMode) -> Self {
|
||||||
match value {
|
match value {
|
||||||
|
@ -39,7 +40,7 @@ impl From<KeyCollectionMode> for sys::napi_key_collection_mode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
pub enum KeyFilter {
|
pub enum KeyFilter {
|
||||||
AllProperties,
|
AllProperties,
|
||||||
Writable,
|
Writable,
|
||||||
|
@ -49,7 +50,7 @@ pub enum KeyFilter {
|
||||||
SkipSymbols,
|
SkipSymbols,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
impl TryFrom<sys::napi_key_filter> for KeyFilter {
|
impl TryFrom<sys::napi_key_filter> for KeyFilter {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
|
@ -61,12 +62,11 @@ impl TryFrom<sys::napi_key_filter> for KeyFilter {
|
||||||
sys::napi_key_filter::napi_key_configurable => Ok(Self::Configurable),
|
sys::napi_key_filter::napi_key_configurable => Ok(Self::Configurable),
|
||||||
sys::napi_key_filter::napi_key_skip_strings => Ok(Self::SkipStrings),
|
sys::napi_key_filter::napi_key_skip_strings => Ok(Self::SkipStrings),
|
||||||
sys::napi_key_filter::napi_key_skip_symbols => Ok(Self::SkipSymbols),
|
sys::napi_key_filter::napi_key_skip_symbols => Ok(Self::SkipSymbols),
|
||||||
_ => Err(Error::from_status(Status::Unknown)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
impl From<KeyFilter> for sys::napi_key_filter {
|
impl From<KeyFilter> for sys::napi_key_filter {
|
||||||
fn from(value: KeyFilter) -> Self {
|
fn from(value: KeyFilter) -> Self {
|
||||||
match value {
|
match value {
|
||||||
|
@ -80,13 +80,13 @@ impl From<KeyFilter> for sys::napi_key_filter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
pub enum KeyConversion {
|
pub enum KeyConversion {
|
||||||
KeepNumbers,
|
KeepNumbers,
|
||||||
NumbersToStrings,
|
NumbersToStrings,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
impl TryFrom<sys::napi_key_conversion> for KeyConversion {
|
impl TryFrom<sys::napi_key_conversion> for KeyConversion {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
|
@ -94,12 +94,11 @@ impl TryFrom<sys::napi_key_conversion> for KeyConversion {
|
||||||
match value {
|
match value {
|
||||||
sys::napi_key_conversion::napi_key_keep_numbers => Ok(Self::KeepNumbers),
|
sys::napi_key_conversion::napi_key_keep_numbers => Ok(Self::KeepNumbers),
|
||||||
sys::napi_key_conversion::napi_key_numbers_to_strings => Ok(Self::NumbersToStrings),
|
sys::napi_key_conversion::napi_key_numbers_to_strings => Ok(Self::NumbersToStrings),
|
||||||
_ => Err(Error::from_status(Status::Unknown)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
impl From<KeyConversion> for sys::napi_key_conversion {
|
impl From<KeyConversion> for sys::napi_key_conversion {
|
||||||
fn from(value: KeyConversion) -> Self {
|
fn from(value: KeyConversion) -> Self {
|
||||||
match value {
|
match value {
|
||||||
|
|
|
@ -13,11 +13,11 @@ pub struct Property<'env> {
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
pub enum PropertyAttributes {
|
pub enum PropertyAttributes {
|
||||||
Default = sys::napi_property_attributes::napi_default.0 as _,
|
Default = sys::napi_property_attributes::napi_default as _,
|
||||||
Writable = sys::napi_property_attributes::napi_writable.0 as _,
|
Writable = sys::napi_property_attributes::napi_writable as _,
|
||||||
Enumerable = sys::napi_property_attributes::napi_enumerable.0 as _,
|
Enumerable = sys::napi_property_attributes::napi_enumerable as _,
|
||||||
Configurable = sys::napi_property_attributes::napi_configurable.0 as _,
|
Configurable = sys::napi_property_attributes::napi_configurable as _,
|
||||||
Static = sys::napi_property_attributes::napi_static.0 as _,
|
Static = sys::napi_property_attributes::napi_static as _,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<PropertyAttributes> for sys::napi_property_attributes {
|
impl From<PropertyAttributes> for sys::napi_property_attributes {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use std::result::Result as StdResult;
|
use std::result::Result as StdResult;
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
|
||||||
use serde::{ser, Serialize, Serializer};
|
use serde::{ser, Serialize, Serializer};
|
||||||
|
@ -92,13 +92,21 @@ impl<'env> Serializer for Ser<'env> {
|
||||||
self.0.create_uint32(v).map(|js_number| js_number.0)
|
self.0.create_uint32(v).map(|js_number| js_number.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(any(napi2, napi3, napi4, napi5), not(napi6)))]
|
#[cfg(all(
|
||||||
|
any(
|
||||||
|
feature = "napi2",
|
||||||
|
feature = "napi3",
|
||||||
|
feature = "napi4",
|
||||||
|
feature = "napi5"
|
||||||
|
),
|
||||||
|
not(feature = "napi6")
|
||||||
|
))]
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize_u64(self, v: u64) -> Result<Self::Ok> {
|
fn serialize_u64(self, v: u64) -> Result<Self::Ok> {
|
||||||
self.0.create_int64(v as _).map(|js_number| js_number.0)
|
self.0.create_int64(v as _).map(|js_number| js_number.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize_u64(self, v: u64) -> Result<Self::Ok> {
|
fn serialize_u64(self, v: u64) -> Result<Self::Ok> {
|
||||||
self
|
self
|
||||||
|
@ -107,13 +115,21 @@ impl<'env> Serializer for Ser<'env> {
|
||||||
.map(|js_number| js_number.raw)
|
.map(|js_number| js_number.raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(any(napi2, napi3, napi4, napi5), not(napi6)))]
|
#[cfg(all(
|
||||||
|
any(
|
||||||
|
feature = "napi2",
|
||||||
|
feature = "napi3",
|
||||||
|
feature = "napi4",
|
||||||
|
feature = "napi5"
|
||||||
|
),
|
||||||
|
not(feature = "napi6")
|
||||||
|
))]
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize_u128(self, v: u128) -> Result<Self::Ok> {
|
fn serialize_u128(self, v: u128) -> Result<Self::Ok> {
|
||||||
self.0.create_string(v.to_string().as_str()).map(|v| v.0)
|
self.0.create_string(v.to_string().as_str()).map(|v| v.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize_u128(self, v: u128) -> Result<Self::Ok> {
|
fn serialize_u128(self, v: u128) -> Result<Self::Ok> {
|
||||||
let words_ref = &v as *const _;
|
let words_ref = &v as *const _;
|
||||||
|
@ -124,13 +140,21 @@ impl<'env> Serializer for Ser<'env> {
|
||||||
.map(|v| v.raw)
|
.map(|v| v.raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(any(napi2, napi3, napi4, napi5), not(napi6)))]
|
#[cfg(all(
|
||||||
|
any(
|
||||||
|
feature = "napi2",
|
||||||
|
feature = "napi3",
|
||||||
|
feature = "napi4",
|
||||||
|
feature = "napi5"
|
||||||
|
),
|
||||||
|
not(feature = "napi6")
|
||||||
|
))]
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize_i128(self, v: i128) -> Result<Self::Ok> {
|
fn serialize_i128(self, v: i128) -> Result<Self::Ok> {
|
||||||
self.0.create_string(v.to_string().as_str()).map(|v| v.0)
|
self.0.create_string(v.to_string().as_str()).map(|v| v.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize_i128(self, v: i128) -> Result<Self::Ok> {
|
fn serialize_i128(self, v: i128) -> Result<Self::Ok> {
|
||||||
let words_ref = &(v as u128) as *const _;
|
let words_ref = &(v as u128) as *const _;
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
use std::convert::TryFrom;
|
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
|
|
||||||
use crate::{sys, Error, Result, Status};
|
use crate::{sys, Error, Result, Status};
|
||||||
|
|
||||||
|
#[repr(u8)]
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash)]
|
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash)]
|
||||||
pub enum ValueType {
|
pub enum ValueType {
|
||||||
Unknown = 100,
|
|
||||||
Undefined = 0,
|
Undefined = 0,
|
||||||
Null = 1,
|
Null = 1,
|
||||||
Boolean = 2,
|
Boolean = 2,
|
||||||
|
@ -15,8 +14,9 @@ pub enum ValueType {
|
||||||
Object = 6,
|
Object = 6,
|
||||||
Function = 7,
|
Function = 7,
|
||||||
External = 8,
|
External = 8,
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
Bigint = 9,
|
Bigint = 9,
|
||||||
|
Unknown = 255,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryInto<sys::napi_valuetype> for ValueType {
|
impl TryInto<sys::napi_valuetype> for ValueType {
|
||||||
|
@ -25,7 +25,7 @@ impl TryInto<sys::napi_valuetype> for ValueType {
|
||||||
fn try_into(self) -> Result<sys::napi_valuetype> {
|
fn try_into(self) -> Result<sys::napi_valuetype> {
|
||||||
match self {
|
match self {
|
||||||
ValueType::Unknown => Err(Error::from_status(Status::Unknown)),
|
ValueType::Unknown => Err(Error::from_status(Status::Unknown)),
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
ValueType::Bigint => Ok(sys::napi_valuetype::napi_bigint),
|
ValueType::Bigint => Ok(sys::napi_valuetype::napi_bigint),
|
||||||
ValueType::Boolean => Ok(sys::napi_valuetype::napi_boolean),
|
ValueType::Boolean => Ok(sys::napi_valuetype::napi_boolean),
|
||||||
ValueType::External => Ok(sys::napi_valuetype::napi_external),
|
ValueType::External => Ok(sys::napi_valuetype::napi_external),
|
||||||
|
@ -40,23 +40,20 @@ impl TryInto<sys::napi_valuetype> for ValueType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<sys::napi_valuetype> for ValueType {
|
impl From<sys::napi_valuetype> for ValueType {
|
||||||
type Error = Error;
|
fn from(value: sys::napi_valuetype) -> Self {
|
||||||
|
|
||||||
fn try_from(value: sys::napi_valuetype) -> Result<Self> {
|
|
||||||
match value {
|
match value {
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
sys::napi_valuetype::napi_bigint => Ok(ValueType::Bigint),
|
sys::napi_valuetype::napi_bigint => ValueType::Bigint,
|
||||||
sys::napi_valuetype::napi_boolean => Ok(ValueType::Boolean),
|
sys::napi_valuetype::napi_boolean => ValueType::Boolean,
|
||||||
sys::napi_valuetype::napi_external => Ok(ValueType::External),
|
sys::napi_valuetype::napi_external => ValueType::External,
|
||||||
sys::napi_valuetype::napi_function => Ok(ValueType::Function),
|
sys::napi_valuetype::napi_function => ValueType::Function,
|
||||||
sys::napi_valuetype::napi_null => Ok(ValueType::Null),
|
sys::napi_valuetype::napi_null => ValueType::Null,
|
||||||
sys::napi_valuetype::napi_number => Ok(ValueType::Number),
|
sys::napi_valuetype::napi_number => ValueType::Number,
|
||||||
sys::napi_valuetype::napi_object => Ok(ValueType::Object),
|
sys::napi_valuetype::napi_object => ValueType::Object,
|
||||||
sys::napi_valuetype::napi_string => Ok(ValueType::String),
|
sys::napi_valuetype::napi_string => ValueType::String,
|
||||||
sys::napi_valuetype::napi_symbol => Ok(ValueType::Symbol),
|
sys::napi_valuetype::napi_symbol => ValueType::Symbol,
|
||||||
sys::napi_valuetype::napi_undefined => Ok(ValueType::Undefined),
|
sys::napi_valuetype::napi_undefined => ValueType::Undefined,
|
||||||
_ => Err(Error::from_status(Status::Unknown)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,23 +92,22 @@
|
||||||
|
|
||||||
mod async_work;
|
mod async_work;
|
||||||
mod call_context;
|
mod call_context;
|
||||||
|
#[cfg(feature = "napi3")]
|
||||||
mod cleanup_env;
|
mod cleanup_env;
|
||||||
mod env;
|
mod env;
|
||||||
mod error;
|
mod error;
|
||||||
mod js_values;
|
mod js_values;
|
||||||
mod module;
|
mod module;
|
||||||
#[cfg(all(feature = "libuv", napi4))]
|
#[cfg(all(feature = "tokio_rt", feature = "napi4"))]
|
||||||
mod promise;
|
mod promise;
|
||||||
mod status;
|
mod status;
|
||||||
mod task;
|
mod task;
|
||||||
#[cfg(napi3)]
|
#[cfg(feature = "napi3")]
|
||||||
pub use cleanup_env::CleanupEnvHook;
|
pub use cleanup_env::CleanupEnvHook;
|
||||||
#[cfg(napi4)]
|
#[cfg(feature = "napi4")]
|
||||||
pub mod threadsafe_function;
|
pub mod threadsafe_function;
|
||||||
#[cfg(all(feature = "tokio_rt", napi4))]
|
#[cfg(all(feature = "tokio_rt", feature = "napi4"))]
|
||||||
mod tokio_rt;
|
mod tokio_rt;
|
||||||
#[cfg(all(feature = "libuv", napi4))]
|
|
||||||
mod uv;
|
|
||||||
mod version;
|
mod version;
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
mod win_delay_load_hook;
|
mod win_delay_load_hook;
|
||||||
|
@ -124,7 +123,7 @@ pub use status::Status;
|
||||||
pub use task::Task;
|
pub use task::Task;
|
||||||
pub use version::NodeVersion;
|
pub use version::NodeVersion;
|
||||||
|
|
||||||
#[cfg(all(feature = "tokio_rt", napi4))]
|
#[cfg(all(feature = "tokio_rt", feature = "napi4"))]
|
||||||
pub use tokio_rt::shutdown as shutdown_tokio_rt;
|
pub use tokio_rt::shutdown as shutdown_tokio_rt;
|
||||||
|
|
||||||
#[cfg(feature = "serde-json")]
|
#[cfg(feature = "serde-json")]
|
||||||
|
@ -147,7 +146,7 @@ pub type ContextlessResult<T> = Result<Option<T>>;
|
||||||
macro_rules! register_module {
|
macro_rules! register_module {
|
||||||
($module_name:ident, $init:ident) => {
|
($module_name:ident, $init:ident) => {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(all(feature = "tokio_rt", napi4))]
|
#[cfg(all(feature = "tokio_rt", feature = "napi4"))]
|
||||||
fn check_status(code: $crate::sys::napi_status) -> Result<()> {
|
fn check_status(code: $crate::sys::napi_status) -> Result<()> {
|
||||||
use $crate::{Error, Status};
|
use $crate::{Error, Status};
|
||||||
let status = Status::from(code);
|
let status = Status::from(code);
|
||||||
|
@ -163,7 +162,7 @@ macro_rules! register_module {
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use $crate::{sys, Env, JsObject, NapiValue};
|
use $crate::{sys, Env, JsObject, NapiValue};
|
||||||
|
|
||||||
#[cfg(all(feature = "tokio_rt", napi4))]
|
#[cfg(all(feature = "tokio_rt", feature = "napi4"))]
|
||||||
use $crate::shutdown_tokio_rt;
|
use $crate::shutdown_tokio_rt;
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -175,11 +174,11 @@ macro_rules! register_module {
|
||||||
let mut exports: JsObject = JsObject::from_raw_unchecked(raw_env, raw_exports);
|
let mut exports: JsObject = JsObject::from_raw_unchecked(raw_env, raw_exports);
|
||||||
let mut cjs_module = Module { env, exports };
|
let mut cjs_module = Module { env, exports };
|
||||||
let result = $init(&mut cjs_module);
|
let result = $init(&mut cjs_module);
|
||||||
#[cfg(all(feature = "tokio_rt", napi4))]
|
#[cfg(all(feature = "tokio_rt", feature = "napi4"))]
|
||||||
let hook_result = check_status(unsafe {
|
let hook_result = check_status(unsafe {
|
||||||
sys::napi_add_env_cleanup_hook(raw_env, Some(shutdown_tokio_rt), ptr::null_mut())
|
sys::napi_add_env_cleanup_hook(raw_env, Some(shutdown_tokio_rt), ptr::null_mut())
|
||||||
});
|
});
|
||||||
#[cfg(not(all(feature = "tokio_rt", napi4)))]
|
#[cfg(not(all(feature = "tokio_rt", feature = "napi4")))]
|
||||||
let hook_result = Ok(());
|
let hook_result = Ok(());
|
||||||
match hook_result.and_then(move |_| result) {
|
match hook_result.and_then(move |_| result) {
|
||||||
Ok(_) => cjs_module.exports.raw(),
|
Ok(_) => cjs_module.exports.raw(),
|
||||||
|
|
|
@ -17,11 +17,11 @@ pub enum Status {
|
||||||
EscapeCalledTwice,
|
EscapeCalledTwice,
|
||||||
HandleScopeMismatch,
|
HandleScopeMismatch,
|
||||||
CallbackScopeMismatch,
|
CallbackScopeMismatch,
|
||||||
#[cfg(napi4)]
|
#[cfg(feature = "napi4")]
|
||||||
QueueFull,
|
QueueFull,
|
||||||
#[cfg(napi4)]
|
#[cfg(feature = "napi4")]
|
||||||
Closing,
|
Closing,
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
BigintExpected,
|
BigintExpected,
|
||||||
Unknown,
|
Unknown,
|
||||||
}
|
}
|
||||||
|
@ -46,11 +46,11 @@ impl From<napi_status> for Status {
|
||||||
napi_status::napi_escape_called_twice => EscapeCalledTwice,
|
napi_status::napi_escape_called_twice => EscapeCalledTwice,
|
||||||
napi_status::napi_handle_scope_mismatch => HandleScopeMismatch,
|
napi_status::napi_handle_scope_mismatch => HandleScopeMismatch,
|
||||||
napi_status::napi_callback_scope_mismatch => CallbackScopeMismatch,
|
napi_status::napi_callback_scope_mismatch => CallbackScopeMismatch,
|
||||||
#[cfg(napi4)]
|
#[cfg(feature = "napi4")]
|
||||||
napi_status::napi_queue_full => QueueFull,
|
napi_status::napi_queue_full => QueueFull,
|
||||||
#[cfg(napi4)]
|
#[cfg(feature = "napi4")]
|
||||||
napi_status::napi_closing => Closing,
|
napi_status::napi_closing => Closing,
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
napi_status::napi_bigint_expected => BigintExpected,
|
napi_status::napi_bigint_expected => BigintExpected,
|
||||||
_ => Unknown,
|
_ => Unknown,
|
||||||
}
|
}
|
||||||
|
@ -75,11 +75,11 @@ impl Into<self::napi_status> for Status {
|
||||||
Self::EscapeCalledTwice => napi_status::napi_escape_called_twice,
|
Self::EscapeCalledTwice => napi_status::napi_escape_called_twice,
|
||||||
Self::HandleScopeMismatch => napi_status::napi_handle_scope_mismatch,
|
Self::HandleScopeMismatch => napi_status::napi_handle_scope_mismatch,
|
||||||
Self::CallbackScopeMismatch => napi_status::napi_callback_scope_mismatch,
|
Self::CallbackScopeMismatch => napi_status::napi_callback_scope_mismatch,
|
||||||
#[cfg(napi4)]
|
#[cfg(feature = "napi4")]
|
||||||
Self::QueueFull => napi_status::napi_queue_full,
|
Self::QueueFull => napi_status::napi_queue_full,
|
||||||
#[cfg(napi4)]
|
#[cfg(feature = "napi4")]
|
||||||
Self::Closing => napi_status::napi_closing,
|
Self::Closing => napi_status::napi_closing,
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "napi6")]
|
||||||
Self::BigintExpected => napi_status::napi_bigint_expected,
|
Self::BigintExpected => napi_status::napi_bigint_expected,
|
||||||
Self::Unknown => napi_status::napi_generic_failure,
|
Self::Unknown => napi_status::napi_generic_failure,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,96 +0,0 @@
|
||||||
extern crate alloc;
|
|
||||||
|
|
||||||
use alloc::alloc::{alloc, Layout};
|
|
||||||
use futures::future::LocalBoxFuture;
|
|
||||||
use futures::task::{waker, ArcWake, Context, Poll};
|
|
||||||
use std::future::Future;
|
|
||||||
use std::os::raw::c_void;
|
|
||||||
use std::pin::Pin;
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use crate::{sys, Error, Result, Status};
|
|
||||||
|
|
||||||
struct Task<'a> {
|
|
||||||
future: LocalBoxFuture<'a, ()>,
|
|
||||||
context: Context<'a>,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct UvWaker(*mut sys::uv_async_t);
|
|
||||||
|
|
||||||
unsafe impl Send for UvWaker {}
|
|
||||||
unsafe impl Sync for UvWaker {}
|
|
||||||
|
|
||||||
impl UvWaker {
|
|
||||||
fn new(event_loop: *mut sys::uv_loop_s) -> Result<UvWaker> {
|
|
||||||
let uv_async_t = unsafe { alloc(Layout::new::<sys::uv_async_t>()) as *mut sys::uv_async_t };
|
|
||||||
unsafe {
|
|
||||||
let status = sys::uv_async_init(event_loop, uv_async_t, Some(poll_future));
|
|
||||||
if status != 0 {
|
|
||||||
return Err(Error::new(
|
|
||||||
Status::Unknown,
|
|
||||||
"Non-zero status returned from uv_async_init".to_owned(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Ok(UvWaker(uv_async_t))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn assign_task(&self, mut task: Task) {
|
|
||||||
if !task.poll_future() {
|
|
||||||
let arc_task = Arc::new(task);
|
|
||||||
unsafe {
|
|
||||||
sys::uv_handle_set_data(
|
|
||||||
self.0 as *mut sys::uv_handle_t,
|
|
||||||
Arc::into_raw(arc_task) as *mut c_void,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
unsafe { sys::uv_close(self.0 as *mut sys::uv_handle_t, None) };
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ArcWake for UvWaker {
|
|
||||||
fn wake_by_ref(arc_self: &Arc<Self>) {
|
|
||||||
let status = unsafe { sys::uv_async_send(arc_self.0) };
|
|
||||||
assert!(status == 0, "wake_uv_async_by_ref failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn execute(event_loop: *mut sys::uv_loop_s, future: LocalBoxFuture<()>) -> Result<()> {
|
|
||||||
let uv_waker = UvWaker::new(event_loop)?;
|
|
||||||
let arc_waker = Arc::new(uv_waker);
|
|
||||||
let waker_to_poll = Arc::clone(&arc_waker);
|
|
||||||
let waker = waker(arc_waker);
|
|
||||||
let context = Context::from_waker(&waker);
|
|
||||||
let task = Task { future, context };
|
|
||||||
waker_to_poll.assign_task(task);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Task<'a> {
|
|
||||||
fn poll_future(&mut self) -> bool {
|
|
||||||
let mut pinned = Pin::new(&mut self.future);
|
|
||||||
let fut_mut = pinned.as_mut();
|
|
||||||
match fut_mut.poll(&mut self.context) {
|
|
||||||
Poll::Ready(_) => true,
|
|
||||||
Poll::Pending => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe extern "C" fn poll_future(handle: *mut sys::uv_async_t) {
|
|
||||||
let data_ptr = sys::uv_handle_get_data(handle as *mut sys::uv_handle_t) as *mut Task;
|
|
||||||
let mut task = Arc::from_raw(data_ptr);
|
|
||||||
if let Some(mut_task) = Arc::get_mut(&mut task) {
|
|
||||||
if mut_task.poll_future() {
|
|
||||||
sys::uv_close(handle as *mut sys::uv_handle_t, None);
|
|
||||||
} else {
|
|
||||||
Arc::into_raw(task);
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
Arc::into_raw(task);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -10,14 +10,14 @@ readme = "README.md"
|
||||||
repository = "https://github.com/napi-rs/napi-rs"
|
repository = "https://github.com/napi-rs/napi-rs"
|
||||||
version = "0.4.7"
|
version = "0.4.7"
|
||||||
|
|
||||||
[target.'cfg(windows)'.build-dependencies]
|
[features]
|
||||||
tar = "0.4"
|
napi1 = []
|
||||||
|
napi2 = ["napi1"]
|
||||||
|
napi3 = ["napi2"]
|
||||||
|
napi4 = ["napi3"]
|
||||||
|
napi5 = ["napi4"]
|
||||||
|
napi6 = ["napi5"]
|
||||||
|
napi7 = ["napi6"]
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
bindgen = {version = "0.55", default-features = false, features = ["logging", "runtime"]}
|
napi-build = {version = "0.2", path = "../build"}
|
||||||
glob = "0.3"
|
|
||||||
regex = "1.3"
|
|
||||||
semver = "0.11"
|
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
|
||||||
rustc-args = ["--cfg", "napidocsrs"]
|
|
||||||
|
|
125
sys/build.rs
125
sys/build.rs
|
@ -1,125 +0,0 @@
|
||||||
extern crate bindgen;
|
|
||||||
extern crate glob;
|
|
||||||
extern crate semver;
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
extern crate tar;
|
|
||||||
|
|
||||||
use glob::glob;
|
|
||||||
|
|
||||||
use std::env;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
use std::process::Command;
|
|
||||||
|
|
||||||
#[cfg(not(any(target_os = "windows", napidocsrs)))]
|
|
||||||
const NODE_PRINT_EXEC_PATH: &'static str = "console.log(process.execPath)";
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let node_full_version =
|
|
||||||
String::from_utf8(Command::new("node").arg("-v").output().unwrap().stdout).unwrap();
|
|
||||||
let node_version = semver::Version::parse(node_full_version.as_str().get(1..).unwrap()).unwrap();
|
|
||||||
|
|
||||||
let node_major_version = node_version.major;
|
|
||||||
|
|
||||||
println!("cargo:rerun-if-env-changed=NODE_INCLUDE_PATH");
|
|
||||||
for entry in glob("./src/**/*.*").unwrap() {
|
|
||||||
println!(
|
|
||||||
"cargo:rerun-if-changed={}",
|
|
||||||
entry.unwrap().to_str().unwrap()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if node_major_version < 8 && node_version.minor < 9 {
|
|
||||||
panic!("node version is too low")
|
|
||||||
}
|
|
||||||
|
|
||||||
let node_include_path_buf = find_node_include_path(node_full_version.trim_end());
|
|
||||||
|
|
||||||
let node_include_path = match env::var("NODE_INCLUDE_PATH") {
|
|
||||||
Ok(node_include_path) => node_include_path,
|
|
||||||
Err(_) => node_include_path_buf.to_str().unwrap().to_owned(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
|
|
||||||
|
|
||||||
let mut sys_bindings_path = PathBuf::from("src");
|
|
||||||
sys_bindings_path.push("bindings.h");
|
|
||||||
|
|
||||||
let mut bindgen_builder = bindgen::Builder::default()
|
|
||||||
.derive_default(true)
|
|
||||||
.header(sys_bindings_path.to_str().unwrap().to_owned())
|
|
||||||
.clang_arg(format!("-I{}", node_include_path))
|
|
||||||
.clang_arg("-target")
|
|
||||||
.clang_arg(env::var("TARGET").unwrap());
|
|
||||||
|
|
||||||
if let Ok(uv_include_path) = env::var("NAPI_RS_INCLUDE_PATH") {
|
|
||||||
bindgen_builder = bindgen_builder.clang_arg(format!("-I{}", uv_include_path));
|
|
||||||
}
|
|
||||||
if cfg!(target_os = "freebsd") {
|
|
||||||
bindgen_builder = bindgen_builder.clang_arg(format!(
|
|
||||||
"-I{}",
|
|
||||||
node_include_path_buf.parent().unwrap().to_str().unwrap()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
bindgen_builder
|
|
||||||
.newtype_enum("(napi_|uv_).+")
|
|
||||||
.whitelist_function("(napi_|uv_|extras_).+")
|
|
||||||
.whitelist_type("(napi_|uv_|extras_).+")
|
|
||||||
.generate()
|
|
||||||
.expect("Unable to generate napi bindings")
|
|
||||||
.write_to_file(out_path.join("bindings.rs"))
|
|
||||||
.expect("Unable to write napi bindings");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(all(target_os = "windows", not(napidocsrs)))]
|
|
||||||
fn find_node_include_path(node_full_version: &str) -> PathBuf {
|
|
||||||
let mut out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
|
|
||||||
out_path.push(format!("node-headers-{}.tar.gz", node_full_version));
|
|
||||||
let mut header_dist_path = PathBuf::from(&PathBuf::from(&out_path).parent().unwrap());
|
|
||||||
let unpack_path = PathBuf::from(&header_dist_path);
|
|
||||||
header_dist_path.push(format!("node-{}", node_full_version));
|
|
||||||
header_dist_path.push("include");
|
|
||||||
header_dist_path.push("node");
|
|
||||||
if !header_dist_path.exists() {
|
|
||||||
let script = r#"require('https').get(process.release.headersUrl, function (res) {
|
|
||||||
res.pipe(require('zlib').createUnzip()).pipe(process.stdout)
|
|
||||||
})"#;
|
|
||||||
|
|
||||||
let tar_binary = Command::new("node")
|
|
||||||
.arg("-e")
|
|
||||||
.arg(script)
|
|
||||||
.output()
|
|
||||||
.expect("Download headers file failed")
|
|
||||||
.stdout;
|
|
||||||
tar::Archive::new(tar_binary.as_slice())
|
|
||||||
.unpack(&unpack_path)
|
|
||||||
.expect("Unpack headers file failed");
|
|
||||||
};
|
|
||||||
header_dist_path
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(napidocsrs)]
|
|
||||||
fn find_node_include_path(_node_full_version: &str) -> PathBuf {
|
|
||||||
let mut current = env::current_dir().unwrap();
|
|
||||||
current.push(".node-headers");
|
|
||||||
current
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(any(target_os = "windows", napidocsrs)))]
|
|
||||||
fn find_node_include_path(_node_full_version: &str) -> PathBuf {
|
|
||||||
let node_exec_path = String::from_utf8(
|
|
||||||
Command::new("node")
|
|
||||||
.arg("-e")
|
|
||||||
.arg(NODE_PRINT_EXEC_PATH)
|
|
||||||
.output()
|
|
||||||
.unwrap()
|
|
||||||
.stdout,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
PathBuf::from(node_exec_path)
|
|
||||||
.parent()
|
|
||||||
.unwrap()
|
|
||||||
.parent()
|
|
||||||
.unwrap()
|
|
||||||
.join("include/node")
|
|
||||||
}
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include <node_api.h>
|
|
||||||
#include <uv.h>
|
|
1206
sys/src/lib.rs
1206
sys/src/lib.rs
File diff suppressed because it is too large
Load diff
|
@ -1,6 +0,0 @@
|
||||||
#![allow(non_upper_case_globals)]
|
|
||||||
#![allow(non_camel_case_types)]
|
|
||||||
#![allow(non_snake_case)]
|
|
||||||
#![allow(dead_code)]
|
|
||||||
|
|
||||||
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
|
|
|
@ -7,9 +7,13 @@ version = "0.1.0"
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["cdylib"]
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
|
[features]
|
||||||
|
latest = ["napi/napi7"]
|
||||||
|
napi3 = ["napi/napi3"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
napi = {path = "../napi", features = ["libuv", "tokio_rt", "serde-json", "latin1"]}
|
napi = {path = "../napi", features = ["tokio_rt", "serde-json", "latin1"]}
|
||||||
napi-derive = {path = "../napi-derive"}
|
napi-derive = {path = "../napi-derive"}
|
||||||
serde = "1"
|
serde = "1"
|
||||||
serde_bytes = "0.11"
|
serde_bytes = "0.11"
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
import { readFileSync } from 'fs'
|
|
||||||
import { join, resolve } from 'path'
|
|
||||||
|
|
||||||
import test from 'ava'
|
|
||||||
|
|
||||||
import { napiVersion } from '../napi-version'
|
|
||||||
|
|
||||||
const bindings = require('../../index.node')
|
|
||||||
|
|
||||||
let threadMod: any
|
|
||||||
|
|
||||||
try {
|
|
||||||
threadMod = require('worker_threads')
|
|
||||||
} catch (err) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
const filepath = join(__dirname, './example.txt')
|
|
||||||
|
|
||||||
test('should execute future on libuv thread pool', async (t) => {
|
|
||||||
if (napiVersion < 4) {
|
|
||||||
t.is(bindings.uvReadFile, undefined)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const fileContent = await bindings.uvReadFile(filepath)
|
|
||||||
t.true(Buffer.isBuffer(fileContent))
|
|
||||||
t.deepEqual(readFileSync(filepath), fileContent)
|
|
||||||
})
|
|
||||||
|
|
||||||
if (threadMod && napiVersion >= 4) {
|
|
||||||
test('should execute future on libuv thread pool of "Worker"', async (t) => {
|
|
||||||
// Test in threads if current Node.js supports "worker_threads".`
|
|
||||||
|
|
||||||
const { Worker } = threadMod
|
|
||||||
const script = resolve(__dirname, './uv_worker.js')
|
|
||||||
const worker = new Worker(script)
|
|
||||||
const success = await new Promise((resolve) => {
|
|
||||||
worker.on('message', (success: boolean) => {
|
|
||||||
resolve(success)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
t.is(success, true)
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
const { readFileSync } = require('fs')
|
|
||||||
const { join } = require('path')
|
|
||||||
const { isMainThread, parentPort } = require('worker_threads')
|
|
||||||
|
|
||||||
const bindings = require('../../index.node')
|
|
||||||
|
|
||||||
const filepath = join(__dirname, './example.txt')
|
|
||||||
|
|
||||||
if (!isMainThread) {
|
|
||||||
;(async () => {
|
|
||||||
const fileContent = await bindings.uvReadFile(filepath)
|
|
||||||
const success =
|
|
||||||
Buffer.isBuffer(fileContent) &&
|
|
||||||
readFileSync(filepath).toString('utf8') === fileContent.toString('utf8')
|
|
||||||
parentPort.postMessage(success)
|
|
||||||
})().catch((e) => {
|
|
||||||
throw e
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -2,9 +2,11 @@
|
||||||
"name": "test-module",
|
"name": "test-module",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "cargo build && node ../scripts/index.js build",
|
"build": "cargo build --features \"latest\" && node ../scripts/index.js build",
|
||||||
"build-aarch64": "cargo build --target aarch64-unknown-linux-gnu && node ../scripts/index.js build --target-triple aarch64-unknown-linux-gnu",
|
"build-napi3": "cargo build --features \"napi3\" && node ../scripts/index.js build",
|
||||||
"build-release": "cargo build --release && node ../scripts/index.js build --release",
|
"build-aarch64": "cargo build --features \"latest\" --target aarch64-unknown-linux-gnu && node ../scripts/index.js build --target-triple aarch64-unknown-linux-gnu",
|
||||||
|
"build-i686": "cargo build --features \"latest\" --target i686-pc-windows-msvc && node ../scripts/index.js build --target-triple i686-pc-windows-msvc",
|
||||||
|
"build-release": "cargo build --features \"latest\" --release && node ../scripts/index.js build --release",
|
||||||
"test": "node ./index.js"
|
"test": "node ./index.js"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,17 +7,14 @@ extern crate serde_derive;
|
||||||
|
|
||||||
use napi::{Module, Result};
|
use napi::{Module, Result};
|
||||||
|
|
||||||
#[cfg(napi3)]
|
|
||||||
mod cleanup_env;
|
mod cleanup_env;
|
||||||
#[cfg(napi4)]
|
#[cfg(feature = "latest")]
|
||||||
mod libuv;
|
|
||||||
#[cfg(napi4)]
|
|
||||||
mod napi4;
|
mod napi4;
|
||||||
#[cfg(napi5)]
|
#[cfg(feature = "latest")]
|
||||||
mod napi5;
|
mod napi5;
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "latest")]
|
||||||
mod napi6;
|
mod napi6;
|
||||||
#[cfg(napi4)]
|
#[cfg(feature = "latest")]
|
||||||
mod tokio_rt;
|
mod tokio_rt;
|
||||||
|
|
||||||
mod array;
|
mod array;
|
||||||
|
@ -58,17 +55,14 @@ fn init(module: &mut Module) -> Result<()> {
|
||||||
env::register_js(module)?;
|
env::register_js(module)?;
|
||||||
object::register_js(module)?;
|
object::register_js(module)?;
|
||||||
global::register_js(module)?;
|
global::register_js(module)?;
|
||||||
#[cfg(napi3)]
|
|
||||||
cleanup_env::register_js(module)?;
|
cleanup_env::register_js(module)?;
|
||||||
#[cfg(napi4)]
|
#[cfg(feature = "latest")]
|
||||||
napi4::register_js(module)?;
|
napi4::register_js(module)?;
|
||||||
#[cfg(napi4)]
|
#[cfg(feature = "latest")]
|
||||||
tokio_rt::register_js(module)?;
|
tokio_rt::register_js(module)?;
|
||||||
#[cfg(napi4)]
|
#[cfg(feature = "latest")]
|
||||||
libuv::read_file::register_js(module)?;
|
|
||||||
#[cfg(napi5)]
|
|
||||||
napi5::register_js(module)?;
|
napi5::register_js(module)?;
|
||||||
#[cfg(napi6)]
|
#[cfg(feature = "latest")]
|
||||||
napi6::register_js(module)?;
|
napi6::register_js(module)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
pub mod read_file;
|
|
|
@ -1,28 +0,0 @@
|
||||||
use std::fs;
|
|
||||||
use std::thread;
|
|
||||||
|
|
||||||
use futures::channel::oneshot;
|
|
||||||
use futures::prelude::*;
|
|
||||||
use napi::{CallContext, Error, JsObject, JsString, Module, Result, Status};
|
|
||||||
|
|
||||||
#[js_function(1)]
|
|
||||||
pub fn uv_read_file(ctx: CallContext) -> Result<JsObject> {
|
|
||||||
let path = ctx.get::<JsString>(0)?;
|
|
||||||
let (sender, receiver) = oneshot::channel();
|
|
||||||
let p = path.into_utf8()?.to_owned()?;
|
|
||||||
thread::spawn(|| {
|
|
||||||
let res = fs::read(p).map_err(|e| Error::new(Status::Unknown, format!("{}", e)));
|
|
||||||
sender.send(res).expect("Send data failed");
|
|
||||||
});
|
|
||||||
ctx.env.execute(
|
|
||||||
receiver
|
|
||||||
.map_err(|e| Error::new(Status::Unknown, format!("{}", e)))
|
|
||||||
.map(|x| x.and_then(|x| x)),
|
|
||||||
|&mut env, data| env.create_buffer_with_data(data).map(|v| v.into_raw()),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn register_js(module: &mut Module) -> Result<()> {
|
|
||||||
module.create_named_method("uvReadFile", uv_read_file)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
Loading…
Reference in a new issue