diff --git a/.cirrus.yml b/.cirrus.yml index 31b90518..dcac4249 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -7,7 +7,7 @@ task: DEBUG: 'napi:*' setup_script: - 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 - sh rustup.sh -y --profile minimal --default-toolchain stable - . $HOME/.cargo/env diff --git a/.github/workflows/bench.yaml b/.github/workflows/bench.yaml index a7f15222..901da01e 100644 --- a/.github/workflows/bench.yaml +++ b/.github/workflows/bench.yaml @@ -18,9 +18,10 @@ jobs: - uses: actions/checkout@v2 - name: Setup node - uses: actions/setup-node@v1 + uses: actions/setup-node@v2-beta with: node-version: 14 + check-latest: true - name: Install uses: actions-rs/toolchain@v1 diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 9db6519c..5a7bb3f6 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -14,9 +14,10 @@ jobs: - uses: actions/checkout@v2 - name: Setup node - uses: actions/setup-node@v1 + uses: actions/setup-node@v2-beta with: - node-version: 12 + node-version: 14 + check-latest: true - name: Install uses: actions-rs/toolchain@v1 diff --git a/.github/workflows/linux-aarch64.yaml b/.github/workflows/linux-aarch64.yaml index 9794e351..93f14587 100644 --- a/.github/workflows/linux-aarch64.yaml +++ b/.github/workflows/linux-aarch64.yaml @@ -21,9 +21,10 @@ jobs: - uses: actions/checkout@v2 - name: Setup node - uses: actions/setup-node@v1 + uses: actions/setup-node@v2-beta with: node-version: 14 + check-latest: true - name: Install uses: actions-rs/toolchain@v1 diff --git a/.github/workflows/linux-musl.yaml b/.github/workflows/linux-musl.yaml index bdfc31ba..753dca8e 100644 --- a/.github/workflows/linux-musl.yaml +++ b/.github/workflows/linux-musl.yaml @@ -42,10 +42,6 @@ jobs: run: | 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 run: | docker run --rm -v $(pwd)/.cargo:/root/.cargo -v $(pwd):/napi-rs -w /napi-rs builder sh -c "yarn build:test && yarn test" diff --git a/.github/workflows/napi3.yaml b/.github/workflows/napi3.yaml index c029fb10..d4da31e8 100644 --- a/.github/workflows/napi3.yaml +++ b/.github/workflows/napi3.yaml @@ -69,16 +69,9 @@ jobs: command: check 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 run: | - yarn --cwd ./test_module --ignore-engines build + yarn --cwd ./test_module --ignore-engines build-napi3 yarn --ignore-engines test env: RUST_BACKTRACE: 1 diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 798d3fd1..832f27a8 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -13,7 +13,7 @@ jobs: strategy: fail-fast: false matrix: - node: ['10', '12', '14'] + node: ['10', '12', '14', '15'] os: [ubuntu-latest, macos-latest, windows-latest] name: stable - ${{ matrix.os }} - node@${{ matrix.node }} @@ -23,19 +23,10 @@ jobs: - uses: actions/checkout@v2 - name: Setup node - uses: actions/setup-node@v1 + uses: actions/setup-node@v2-beta with: node-version: ${{ matrix.node }} - - - 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' + check-latest: true - name: Install uses: actions-rs/toolchain@v1 @@ -81,13 +72,6 @@ jobs: command: check 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 run: | yarn build:test diff --git a/.github/workflows/windows-i686.yml b/.github/workflows/windows-i686.yml index 587b4494..d763d6e0 100644 --- a/.github/workflows/windows-i686.yml +++ b/.github/workflows/windows-i686.yml @@ -17,17 +17,27 @@ jobs: - uses: actions/checkout@v2 - name: Setup node - uses: actions/setup-node@v1 - with: - node-version: 14 + run: choco install nodejs-lts --x86 -y --force - - name: Install llvm - run: choco install -y llvm - - - name: Set llvm path - run: echo "LIBCLANG_PATH=C:\\Program Files\\LLVM\\bin" >> $GITHUB_ENV + - name: Set 32bit NodeJS path + run: | + echo "C:\\Program Files (x86)\\nodejs" >> $GITHUB_PATH 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 uses: actions-rs/toolchain@v1 with: @@ -47,13 +57,13 @@ jobs: uses: actions/cache@v1 with: 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 uses: actions/cache@v1 with: 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 uses: actions-rs/cargo@v1 @@ -61,12 +71,12 @@ jobs: command: check args: --all --bins --examples --tests --target i686-pc-windows-msvc -vvv - - name: Tests - uses: actions-rs/cargo@v1 - timeout-minutes: 5 - with: - command: test - args: -p napi-sys --lib --target i686-pc-windows-msvc -- --nocapture + - name: Build Tests + run: | + yarn --cwd ./test_module build-i686 + yarn test + env: + RUST_BACKTRACE: 1 - name: Clear the cargo caches run: | diff --git a/README.md b/README.md index d308493f..e24d6d2f 100644 --- a/README.md +++ b/README.md @@ -28,9 +28,9 @@ A minimal library for building compiled `NodeJS` add-ons in `Rust`. ## NodeJS -| Node10 | Node 12 | Node14 | -| ------ | ------- | ------ | -| ✓ | ✓ | ✓ | +| Node10 | Node 12 | Node14 | Node15 | +| ------ | ------- | ------ | ------ | +| ✓ | ✓ | ✓ | ✓ | This library depends on N-API and requires `Node@8.9` or later. diff --git a/bench/Cargo.toml b/bench/Cargo.toml index 49b36641..a824ffc2 100644 --- a/bench/Cargo.toml +++ b/bench/Cargo.toml @@ -8,14 +8,8 @@ version = "0.1.0" crate-type = ["cdylib"] [dependencies] -futures = "0.3" -napi = {path = "../napi", features = ["libuv", "tokio_rt", "serde-json", "latin1"]} +napi = {path = "../napi"} 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] napi-build = {path = "../build"} diff --git a/build/src/lib.rs b/build/src/lib.rs index 66a0ac86..b3d387a0 100644 --- a/build/src/lib.rs +++ b/build/src/lib.rs @@ -1,40 +1,11 @@ cfg_if::cfg_if! { - if #[cfg(windows)] { - mod windows; - pub use windows::setup; - } else if #[cfg(target_os = "macos")] { - mod macos; - 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::().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); + if #[cfg(windows)] { + mod windows; + pub use windows::setup; + } else if #[cfg(target_os = "macos")] { + mod macos; + pub use macos::setup; } else { - for version in 2..(napi_version_number + 1) { - println!("cargo:rustc-cfg=napi{}", version); - } + pub fn setup() { } } } diff --git a/build/src/macos.rs b/build/src/macos.rs index 49ecd4c2..46dd742b 100644 --- a/build/src/macos.rs +++ b/build/src/macos.rs @@ -1,8 +1,5 @@ -use crate::*; - pub fn setup() { println!("cargo:rustc-cdylib-link-arg=-Wl"); println!("cargo:rustc-cdylib-link-arg=-undefined"); println!("cargo:rustc-cdylib-link-arg=dynamic_lookup"); - setup_napi_feature(); } diff --git a/build/src/windows.rs b/build/src/windows.rs index d493eea8..830def4b 100644 --- a/build/src/windows.rs +++ b/build/src/windows.rs @@ -1,9 +1,9 @@ -use crate::*; use std::collections::hash_map::DefaultHasher; use std::fs::{metadata, write}; use std::hash::{Hash, Hasher}; use std::io::Read; use std::path::PathBuf; +use std::process::Command; fn get_node_version() -> std::io::Result { 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. // Nodejs appears to follow `process.arch`. // 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") .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", - "mips" => "mips", - "powerpc" => "ppc", - "powerpc64" => "ppc64", - "arm" => "arm", + // https://github.com/nodejs/node/issues/25998 + // actually not supported for now + // because we can not get `node.lib` file for `aarch64` device "aarch64" => "arm64", - arch => panic!("Unknown Architecture: {}", arch), + arch => panic!("Unsupported CPU Architecture: {}", 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=/DELAYLOAD:node.exe"); - - setup_napi_feature(); } diff --git a/napi/Cargo.toml b/napi/Cargo.toml index 0628c8fb..c98efa19 100644 --- a/napi/Cargo.toml +++ b/napi/Cargo.toml @@ -10,8 +10,15 @@ repository = "https://github.com/napi-rs/napi-rs" version = "0.5.1" [features] +default = ["napi3"] # for most NodeJS users 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"] tokio_rt = ["futures", "tokio", "once_cell"] @@ -51,4 +58,3 @@ napi-build = {version = "0.2", path = "../build"} [package.metadata.docs.rs] all-features = true -rustc-args = ["--cfg", "napidocsrs"] diff --git a/napi/build.rs b/napi/build.rs deleted file mode 100644 index 1c4d57bc..00000000 --- a/napi/build.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - napi_build::setup_napi_feature(); -} diff --git a/napi/src/env.rs b/napi/src/env.rs index 775f1e8d..cde2109b 100644 --- a/napi/src/env.rs +++ b/napi/src/env.rs @@ -5,30 +5,29 @@ use std::mem; use std::os::raw::{c_char, c_void}; use std::ptr; -use super::cleanup_env::{CleanupEnvHook, CleanupEnvHookData}; use crate::async_work::{self, AsyncWorkPromise}; use crate::error::check_status; use crate::js_values::*; use crate::task::Task; use crate::{sys, Error, NodeVersion, Result, Status}; +#[cfg(feature = "napi3")] +use super::cleanup_env::{CleanupEnvHook, CleanupEnvHookData}; #[cfg(all(feature = "serde-json"))] 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; -#[cfg(napi4)] +#[cfg(feature = "napi4")] 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}; -#[cfg(all(feature = "libuv", napi4))] -use crate::uv; #[cfg(all(feature = "serde-json"))] use serde::de::DeserializeOwned; #[cfg(all(feature = "serde-json"))] use serde::Serialize; -#[cfg(all(feature = "libuv", napi4))] +#[cfg(all(feature = "tokio_rt", feature = "napi4"))] use std::future::Future; -#[cfg(all(feature = "tokio_rt", napi4))] +#[cfg(all(feature = "tokio_rt", feature = "napi4"))] use tokio::sync::mpsc::error::TrySendError; 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)) } - #[cfg(napi6)] + #[cfg(feature = "napi6")] /// [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 { let mut raw_value = ptr::null_mut(); @@ -98,14 +97,14 @@ impl Env { 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 { let mut raw_value = ptr::null_mut(); check_status(unsafe { sys::napi_create_bigint_uint64(self.0, value, &mut raw_value) })?; 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 { let mut raw_value = ptr::null_mut(); 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)) } - #[cfg(napi6)] + #[cfg(feature = "napi6")] pub fn create_bigint_from_u128(&self, value: u128) -> Result { let mut raw_value = ptr::null_mut(); 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)) } - #[cfg(napi6)] + #[cfg(feature = "napi6")] /// [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. pub fn create_bigint_from_words(&self, sign_bit: bool, words: Vec) -> Result { @@ -549,14 +548,14 @@ impl Env { .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> { 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) })?; Ok(uv_loop) } - #[cfg(napi3)] + #[cfg(feature = "napi3")] pub fn add_env_cleanup_hook( &mut self, cleanup_data: T, @@ -581,7 +580,7 @@ impl Env { Ok(CleanupEnvHook(hook_ref)) } - #[cfg(napi3)] + #[cfg(feature = "napi3")] pub fn remove_env_cleanup_hook(&mut self, hook: CleanupEnvHook) -> Result<()> where T: 'static, @@ -591,7 +590,7 @@ impl Env { }) } - #[cfg(napi4)] + #[cfg(feature = "napi4")] pub fn create_threadsafe_function< T: Send, V: NapiValue, @@ -605,31 +604,7 @@ impl Env { ThreadsafeFunction::create(self.0, func, max_queue_size, callback) } - #[cfg(all(feature = "libuv", napi4))] - pub fn execute< - T: 'static + Send, - V: 'static + NapiValue, - F: 'static + Future>, - R: 'static + Send + Sync + FnOnce(&mut Env, T) -> Result, - >( - &self, - deferred: F, - resolver: R, - ) -> Result { - 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))] + #[cfg(all(feature = "tokio_rt", feature = "napi4"))] pub fn execute_tokio_future< T: 'static + Send, V: 'static + NapiValue, @@ -664,7 +639,7 @@ impl Env { Ok(JsObject::from_raw_unchecked(self.0, raw_promise)) } - #[cfg(napi5)] + #[cfg(feature = "napi5")] pub fn create_date(&self, time: f64) -> Result { let mut js_value = ptr::null_mut(); check_status(unsafe { sys::napi_create_date(self.0, time, &mut js_value) })?; @@ -738,6 +713,11 @@ impl Env { let version = unsafe { *result }; 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) { @@ -759,6 +739,7 @@ unsafe extern "C" fn raw_finalize( Box::from_raw(tagged_object); } +#[cfg(feature = "napi3")] unsafe extern "C" fn cleanup_env(hook_data: *mut c_void) { let cleanup_env_hook = Box::from_raw(hook_data as *mut CleanupEnvHookData); (cleanup_env_hook.hook)(cleanup_env_hook.data); diff --git a/napi/src/js_values/arraybuffer.rs b/napi/src/js_values/arraybuffer.rs index 7f08fff4..7d73bf4d 100644 --- a/napi/src/js_values/arraybuffer.rs +++ b/napi/src/js_values/arraybuffer.rs @@ -7,7 +7,7 @@ use std::ptr; use super::{Value, ValueType}; use crate::error::check_status; -use crate::{sys, Error, JsUnknown, NapiValue, Ref, Result, Status}; +use crate::{sys, Error, JsUnknown, NapiValue, Ref, Result}; #[repr(transparent)] #[derive(Debug)] @@ -44,6 +44,7 @@ pub struct JsDataViewValue { pub length: u64, } +#[repr(u8)] #[derive(Debug)] pub enum TypedArrayType { Int8, @@ -55,9 +56,9 @@ pub enum TypedArrayType { Uint32, Float32, Float64, - #[cfg(napi6)] + #[cfg(feature = "napi6")] BigInt64, - #[cfg(napi6)] + #[cfg(feature = "napi6")] BigUint64, } @@ -75,11 +76,10 @@ impl TryFrom for TypedArrayType { 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_float64_array => Ok(Self::Float64), - #[cfg(napi6)] + #[cfg(feature = "napi6")] 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), - _ => Err(Error::from_status(Status::Unknown)), } } } @@ -96,21 +96,21 @@ impl From for sys::napi_typedarray_type { TypedArrayType::Uint32 => sys::napi_typedarray_type::napi_uint32_array, TypedArrayType::Float32 => sys::napi_typedarray_type::napi_float32_array, TypedArrayType::Float64 => sys::napi_typedarray_type::napi_float64_array, - #[cfg(napi6)] + #[cfg(feature = "napi6")] TypedArrayType::BigInt64 => sys::napi_typedarray_type::napi_bigint64_array, - #[cfg(napi6)] + #[cfg(feature = "napi6")] TypedArrayType::BigUint64 => sys::napi_typedarray_type::napi_biguint64_array, } } } impl JsArrayBuffer { - #[cfg(napi7)] + #[cfg(feature = "napi7")] pub fn detach(self) -> Result<()> { check_status(unsafe { sys::napi_detach_arraybuffer(self.0.env, self.0.value) }) } - #[cfg(napi7)] + #[cfg(feature = "napi7")] pub fn is_detached(&self) -> Result { let mut is_detached = false; check_status(unsafe { diff --git a/napi/src/js_values/bigint.rs b/napi/src/js_values/bigint.rs index ce973c31..4f98a988 100644 --- a/napi/src/js_values/bigint.rs +++ b/napi/src/js_values/bigint.rs @@ -71,7 +71,7 @@ impl JsBigint { } #[inline] - #[cfg(napi5)] + #[cfg(feature = "napi5")] pub fn is_date(&self) -> Result { let mut is_date = true; check_status(unsafe { sys::napi_is_date(self.raw.env, self.raw.value, &mut is_date) })?; diff --git a/napi/src/js_values/de.rs b/napi/src/js_values/de.rs index f3f5a6c6..80d71694 100644 --- a/napi/src/js_values/de.rs +++ b/napi/src/js_values/de.rs @@ -4,7 +4,7 @@ use serde::de::Visitor; use serde::de::{DeserializeSeed, EnumAccess, MapAccess, SeqAccess, Unexpected, VariantAccess}; use super::{type_of, NapiValue, Value, ValueType}; -#[cfg(napi6)] +#[cfg(feature = "napi6")] use crate::JsBigint; use crate::{ 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) } } - #[cfg(napi6)] + #[cfg(feature = "napi6")] ValueType::Bigint => { let mut js_bigint = JsBigint::from_raw(self.0.env, self.0.value)?; let (signed, v, _loss) = js_bigint.get_u128()?; diff --git a/napi/src/js_values/mod.rs b/napi/src/js_values/mod.rs index 78c3c1ca..a615604d 100644 --- a/napi/src/js_values/mod.rs +++ b/napi/src/js_values/mod.rs @@ -11,11 +11,11 @@ mod de; mod ser; mod arraybuffer; -#[cfg(napi6)] +#[cfg(feature = "napi6")] mod bigint; mod boolean; mod buffer; -#[cfg(napi5)] +#[cfg(feature = "napi5")] mod date; mod either; mod escapable_handle_scope; @@ -32,11 +32,11 @@ mod value_ref; mod value_type; pub use arraybuffer::*; -#[cfg(napi6)] +#[cfg(feature = "napi6")] pub use bigint::JsBigint; pub use boolean::JsBoolean; pub use buffer::*; -#[cfg(napi5)] +#[cfg(feature = "napi5")] pub use date::*; #[cfg(feature = "serde-json")] 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 { let mut value_type = sys::napi_valuetype::napi_undefined; 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] - #[cfg(napi5)] + #[cfg(feature = "napi5")] pub fn is_date(&self) -> Result { let mut is_date = true; 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 /// return `Array` of property names - #[cfg(napi6)] + #[cfg(feature = "napi6")] pub fn get_all_property_names( &self, mode: KeyCollectionMode, @@ -484,7 +484,7 @@ impl_js_value_methods!(JsNumber); impl_js_value_methods!(JsString); impl_js_value_methods!(JsObject); impl_js_value_methods!(JsGlobal); -#[cfg(napi5)] +#[cfg(feature = "napi5")] impl_js_value_methods!(JsDate); impl_js_value_methods!(JsFunction); 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!(JsObject, Object); impl_napi_value_trait!(JsGlobal, Object); -#[cfg(napi5)] +#[cfg(feature = "napi5")] impl_napi_value_trait!(JsDate, Object); impl_napi_value_trait!(JsTimeout, Object); 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 { self.0.value } diff --git a/napi/src/js_values/object.rs b/napi/src/js_values/object.rs index cfdf6872..9f18f1d4 100644 --- a/napi/src/js_values/object.rs +++ b/napi/src/js_values/object.rs @@ -1,20 +1,22 @@ use super::Value; -#[cfg(napi6)] +#[cfg(feature = "napi6")] use crate::sys; -use crate::{Error, Result, Status}; +#[cfg(feature = "napi6")] +use crate::{Error, Result}; +#[cfg(feature = "napi6")] use std::convert::TryFrom; #[repr(transparent)] #[derive(Debug)] pub struct JsObject(pub(crate) Value); -#[cfg(napi6)] +#[cfg(feature = "napi6")] pub enum KeyCollectionMode { IncludePrototypes, OwnOnly, } -#[cfg(napi6)] +#[cfg(feature = "napi6")] impl TryFrom for KeyCollectionMode { type Error = Error; @@ -22,12 +24,11 @@ impl TryFrom for KeyCollectionMode { match value { sys::napi_key_collection_mode::napi_key_include_prototypes => Ok(Self::IncludePrototypes), 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 for sys::napi_key_collection_mode { fn from(value: KeyCollectionMode) -> Self { match value { @@ -39,7 +40,7 @@ impl From for sys::napi_key_collection_mode { } } -#[cfg(napi6)] +#[cfg(feature = "napi6")] pub enum KeyFilter { AllProperties, Writable, @@ -49,7 +50,7 @@ pub enum KeyFilter { SkipSymbols, } -#[cfg(napi6)] +#[cfg(feature = "napi6")] impl TryFrom for KeyFilter { type Error = Error; @@ -61,12 +62,11 @@ impl TryFrom for KeyFilter { 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_symbols => Ok(Self::SkipSymbols), - _ => Err(Error::from_status(Status::Unknown)), } } } -#[cfg(napi6)] +#[cfg(feature = "napi6")] impl From for sys::napi_key_filter { fn from(value: KeyFilter) -> Self { match value { @@ -80,13 +80,13 @@ impl From for sys::napi_key_filter { } } -#[cfg(napi6)] +#[cfg(feature = "napi6")] pub enum KeyConversion { KeepNumbers, NumbersToStrings, } -#[cfg(napi6)] +#[cfg(feature = "napi6")] impl TryFrom for KeyConversion { type Error = Error; @@ -94,12 +94,11 @@ impl TryFrom for KeyConversion { match value { sys::napi_key_conversion::napi_key_keep_numbers => Ok(Self::KeepNumbers), 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 for sys::napi_key_conversion { fn from(value: KeyConversion) -> Self { match value { diff --git a/napi/src/js_values/object_property.rs b/napi/src/js_values/object_property.rs index 6dd6856f..f0c45390 100644 --- a/napi/src/js_values/object_property.rs +++ b/napi/src/js_values/object_property.rs @@ -13,11 +13,11 @@ pub struct Property<'env> { #[repr(u32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum PropertyAttributes { - Default = sys::napi_property_attributes::napi_default.0 as _, - Writable = sys::napi_property_attributes::napi_writable.0 as _, - Enumerable = sys::napi_property_attributes::napi_enumerable.0 as _, - Configurable = sys::napi_property_attributes::napi_configurable.0 as _, - Static = sys::napi_property_attributes::napi_static.0 as _, + Default = sys::napi_property_attributes::napi_default as _, + Writable = sys::napi_property_attributes::napi_writable as _, + Enumerable = sys::napi_property_attributes::napi_enumerable as _, + Configurable = sys::napi_property_attributes::napi_configurable as _, + Static = sys::napi_property_attributes::napi_static as _, } impl From for sys::napi_property_attributes { diff --git a/napi/src/js_values/ser.rs b/napi/src/js_values/ser.rs index 3552c106..b3239fe8 100644 --- a/napi/src/js_values/ser.rs +++ b/napi/src/js_values/ser.rs @@ -1,5 +1,5 @@ use std::result::Result as StdResult; -#[cfg(napi6)] +#[cfg(feature = "napi6")] use std::slice; 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) } - #[cfg(all(any(napi2, napi3, napi4, napi5), not(napi6)))] + #[cfg(all( + any( + feature = "napi2", + feature = "napi3", + feature = "napi4", + feature = "napi5" + ), + not(feature = "napi6") + ))] #[inline] fn serialize_u64(self, v: u64) -> Result { self.0.create_int64(v as _).map(|js_number| js_number.0) } - #[cfg(napi6)] + #[cfg(feature = "napi6")] #[inline] fn serialize_u64(self, v: u64) -> Result { self @@ -107,13 +115,21 @@ impl<'env> Serializer for Ser<'env> { .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] fn serialize_u128(self, v: u128) -> Result { self.0.create_string(v.to_string().as_str()).map(|v| v.0) } - #[cfg(napi6)] + #[cfg(feature = "napi6")] #[inline] fn serialize_u128(self, v: u128) -> Result { let words_ref = &v as *const _; @@ -124,13 +140,21 @@ impl<'env> Serializer for Ser<'env> { .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] fn serialize_i128(self, v: i128) -> Result { self.0.create_string(v.to_string().as_str()).map(|v| v.0) } - #[cfg(napi6)] + #[cfg(feature = "napi6")] #[inline] fn serialize_i128(self, v: i128) -> Result { let words_ref = &(v as u128) as *const _; diff --git a/napi/src/js_values/value_type.rs b/napi/src/js_values/value_type.rs index 9030e12c..1c58f26e 100644 --- a/napi/src/js_values/value_type.rs +++ b/napi/src/js_values/value_type.rs @@ -1,11 +1,10 @@ -use std::convert::TryFrom; use std::convert::TryInto; use crate::{sys, Error, Result, Status}; +#[repr(u8)] #[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash)] pub enum ValueType { - Unknown = 100, Undefined = 0, Null = 1, Boolean = 2, @@ -15,8 +14,9 @@ pub enum ValueType { Object = 6, Function = 7, External = 8, - #[cfg(napi6)] + #[cfg(feature = "napi6")] Bigint = 9, + Unknown = 255, } impl TryInto for ValueType { @@ -25,7 +25,7 @@ impl TryInto for ValueType { fn try_into(self) -> Result { match self { ValueType::Unknown => Err(Error::from_status(Status::Unknown)), - #[cfg(napi6)] + #[cfg(feature = "napi6")] ValueType::Bigint => Ok(sys::napi_valuetype::napi_bigint), ValueType::Boolean => Ok(sys::napi_valuetype::napi_boolean), ValueType::External => Ok(sys::napi_valuetype::napi_external), @@ -40,23 +40,20 @@ impl TryInto for ValueType { } } -impl TryFrom for ValueType { - type Error = Error; - - fn try_from(value: sys::napi_valuetype) -> Result { +impl From for ValueType { + fn from(value: sys::napi_valuetype) -> Self { match value { - #[cfg(napi6)] - sys::napi_valuetype::napi_bigint => Ok(ValueType::Bigint), - sys::napi_valuetype::napi_boolean => Ok(ValueType::Boolean), - sys::napi_valuetype::napi_external => Ok(ValueType::External), - sys::napi_valuetype::napi_function => Ok(ValueType::Function), - sys::napi_valuetype::napi_null => Ok(ValueType::Null), - sys::napi_valuetype::napi_number => Ok(ValueType::Number), - sys::napi_valuetype::napi_object => Ok(ValueType::Object), - sys::napi_valuetype::napi_string => Ok(ValueType::String), - sys::napi_valuetype::napi_symbol => Ok(ValueType::Symbol), - sys::napi_valuetype::napi_undefined => Ok(ValueType::Undefined), - _ => Err(Error::from_status(Status::Unknown)), + #[cfg(feature = "napi6")] + sys::napi_valuetype::napi_bigint => ValueType::Bigint, + sys::napi_valuetype::napi_boolean => ValueType::Boolean, + sys::napi_valuetype::napi_external => ValueType::External, + sys::napi_valuetype::napi_function => ValueType::Function, + sys::napi_valuetype::napi_null => ValueType::Null, + sys::napi_valuetype::napi_number => ValueType::Number, + sys::napi_valuetype::napi_object => ValueType::Object, + sys::napi_valuetype::napi_string => ValueType::String, + sys::napi_valuetype::napi_symbol => ValueType::Symbol, + sys::napi_valuetype::napi_undefined => ValueType::Undefined, } } } diff --git a/napi/src/lib.rs b/napi/src/lib.rs index ac2f4094..258c1391 100644 --- a/napi/src/lib.rs +++ b/napi/src/lib.rs @@ -92,23 +92,22 @@ mod async_work; mod call_context; +#[cfg(feature = "napi3")] mod cleanup_env; mod env; mod error; mod js_values; mod module; -#[cfg(all(feature = "libuv", napi4))] +#[cfg(all(feature = "tokio_rt", feature = "napi4"))] mod promise; mod status; mod task; -#[cfg(napi3)] +#[cfg(feature = "napi3")] pub use cleanup_env::CleanupEnvHook; -#[cfg(napi4)] +#[cfg(feature = "napi4")] pub mod threadsafe_function; -#[cfg(all(feature = "tokio_rt", napi4))] +#[cfg(all(feature = "tokio_rt", feature = "napi4"))] mod tokio_rt; -#[cfg(all(feature = "libuv", napi4))] -mod uv; mod version; #[cfg(target_os = "windows")] mod win_delay_load_hook; @@ -124,7 +123,7 @@ pub use status::Status; pub use task::Task; 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; #[cfg(feature = "serde-json")] @@ -147,7 +146,7 @@ pub type ContextlessResult = Result>; macro_rules! register_module { ($module_name:ident, $init:ident) => { #[inline] - #[cfg(all(feature = "tokio_rt", napi4))] + #[cfg(all(feature = "tokio_rt", feature = "napi4"))] fn check_status(code: $crate::sys::napi_status) -> Result<()> { use $crate::{Error, Status}; let status = Status::from(code); @@ -163,7 +162,7 @@ macro_rules! register_module { use std::ptr; use $crate::{sys, Env, JsObject, NapiValue}; - #[cfg(all(feature = "tokio_rt", napi4))] + #[cfg(all(feature = "tokio_rt", feature = "napi4"))] use $crate::shutdown_tokio_rt; #[no_mangle] @@ -175,11 +174,11 @@ macro_rules! register_module { let mut exports: JsObject = JsObject::from_raw_unchecked(raw_env, raw_exports); let mut cjs_module = Module { env, exports }; 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 { 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(()); match hook_result.and_then(move |_| result) { Ok(_) => cjs_module.exports.raw(), diff --git a/napi/src/status.rs b/napi/src/status.rs index c2dc62b3..31fbbee8 100644 --- a/napi/src/status.rs +++ b/napi/src/status.rs @@ -17,11 +17,11 @@ pub enum Status { EscapeCalledTwice, HandleScopeMismatch, CallbackScopeMismatch, - #[cfg(napi4)] + #[cfg(feature = "napi4")] QueueFull, - #[cfg(napi4)] + #[cfg(feature = "napi4")] Closing, - #[cfg(napi6)] + #[cfg(feature = "napi6")] BigintExpected, Unknown, } @@ -46,11 +46,11 @@ impl From for Status { napi_status::napi_escape_called_twice => EscapeCalledTwice, napi_status::napi_handle_scope_mismatch => HandleScopeMismatch, napi_status::napi_callback_scope_mismatch => CallbackScopeMismatch, - #[cfg(napi4)] + #[cfg(feature = "napi4")] napi_status::napi_queue_full => QueueFull, - #[cfg(napi4)] + #[cfg(feature = "napi4")] napi_status::napi_closing => Closing, - #[cfg(napi6)] + #[cfg(feature = "napi6")] napi_status::napi_bigint_expected => BigintExpected, _ => Unknown, } @@ -75,11 +75,11 @@ impl Into for Status { Self::EscapeCalledTwice => napi_status::napi_escape_called_twice, Self::HandleScopeMismatch => napi_status::napi_handle_scope_mismatch, Self::CallbackScopeMismatch => napi_status::napi_callback_scope_mismatch, - #[cfg(napi4)] + #[cfg(feature = "napi4")] Self::QueueFull => napi_status::napi_queue_full, - #[cfg(napi4)] + #[cfg(feature = "napi4")] Self::Closing => napi_status::napi_closing, - #[cfg(napi6)] + #[cfg(feature = "napi6")] Self::BigintExpected => napi_status::napi_bigint_expected, Self::Unknown => napi_status::napi_generic_failure, } diff --git a/napi/src/uv.rs b/napi/src/uv.rs deleted file mode 100644 index bf91fc19..00000000 --- a/napi/src/uv.rs +++ /dev/null @@ -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 { - let uv_async_t = unsafe { alloc(Layout::new::()) 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) { - 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); - } -} diff --git a/sys/Cargo.toml b/sys/Cargo.toml index fb8c29c8..2e7bcd8b 100644 --- a/sys/Cargo.toml +++ b/sys/Cargo.toml @@ -10,14 +10,14 @@ readme = "README.md" repository = "https://github.com/napi-rs/napi-rs" version = "0.4.7" -[target.'cfg(windows)'.build-dependencies] -tar = "0.4" +[features] +napi1 = [] +napi2 = ["napi1"] +napi3 = ["napi2"] +napi4 = ["napi3"] +napi5 = ["napi4"] +napi6 = ["napi5"] +napi7 = ["napi6"] [build-dependencies] -bindgen = {version = "0.55", default-features = false, features = ["logging", "runtime"]} -glob = "0.3" -regex = "1.3" -semver = "0.11" - -[package.metadata.docs.rs] -rustc-args = ["--cfg", "napidocsrs"] +napi-build = {version = "0.2", path = "../build"} diff --git a/sys/build.rs b/sys/build.rs deleted file mode 100644 index 2d887b5a..00000000 --- a/sys/build.rs +++ /dev/null @@ -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") -} diff --git a/sys/src/bindings.h b/sys/src/bindings.h deleted file mode 100644 index f7cf3c44..00000000 --- a/sys/src/bindings.h +++ /dev/null @@ -1,2 +0,0 @@ -#include -#include \ No newline at end of file diff --git a/sys/src/lib.rs b/sys/src/lib.rs index 644a4ab9..a90c2bbb 100644 --- a/sys/src/lib.rs +++ b/sys/src/lib.rs @@ -1,2 +1,1204 @@ -mod sys; -pub use sys::*; +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(dead_code)] + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct napi_env__ { + _unused: [u8; 0], +} + +/// Env ptr +pub type napi_env = *mut napi_env__; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct napi_value__ { + _unused: [u8; 0], +} + +/// JsValue ptr +pub type napi_value = *mut napi_value__; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct napi_ref__ { + _unused: [u8; 0], +} +pub type napi_ref = *mut napi_ref__; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct napi_handle_scope__ { + _unused: [u8; 0], +} +pub type napi_handle_scope = *mut napi_handle_scope__; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct napi_escapable_handle_scope__ { + _unused: [u8; 0], +} +pub type napi_escapable_handle_scope = *mut napi_escapable_handle_scope__; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct napi_callback_info__ { + _unused: [u8; 0], +} +pub type napi_callback_info = *mut napi_callback_info__; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct napi_deferred__ { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct uv_loop_s { + _unused: [u8; 0], +} +pub type napi_deferred = *mut napi_deferred__; + +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum napi_property_attributes { + napi_default = 0, + napi_writable = 1 << 0, + napi_enumerable = 1 << 1, + napi_configurable = 1 << 2, + + // Used with napi_define_class to distinguish static properties + // from instance properties. Ignored by napi_define_properties. + napi_static = 1 << 10, +} + +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum napi_valuetype { + napi_undefined, + napi_null, + napi_boolean, + napi_number, + napi_string, + napi_symbol, + napi_object, + napi_function, + napi_external, + #[cfg(feature = "napi6")] + napi_bigint, +} + +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum napi_typedarray_type { + napi_int8_array, + napi_uint8_array, + napi_uint8_clamped_array, + napi_int16_array, + napi_uint16_array, + napi_int32_array, + napi_uint32_array, + napi_float32_array, + napi_float64_array, + #[cfg(feature = "napi6")] + napi_bigint64_array, + #[cfg(feature = "napi6")] + napi_biguint64_array, +} + +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum napi_status { + napi_ok, + napi_invalid_arg, + napi_object_expected, + napi_string_expected, + napi_name_expected, + napi_function_expected, + napi_number_expected, + napi_boolean_expected, + napi_array_expected, + napi_generic_failure, + napi_pending_exception, + napi_cancelled, + napi_escape_called_twice, + napi_handle_scope_mismatch, + napi_callback_scope_mismatch, + #[cfg(feature = "napi4")] + napi_queue_full, + #[cfg(feature = "napi4")] + napi_closing, + #[cfg(feature = "napi6")] + napi_bigint_expected, + #[cfg(feature = "napi6")] + napi_date_expected, + #[cfg(feature = "napi7")] + napi_arraybuffer_expected, + #[cfg(feature = "napi7")] + napi_detachable_arraybuffer_expected, + napi_would_deadlock, // unused +} + +pub type napi_callback = ::std::option::Option< + unsafe extern "C" fn(env: napi_env, info: napi_callback_info) -> napi_value, +>; +pub type napi_finalize = ::std::option::Option< + unsafe extern "C" fn( + env: napi_env, + finalize_data: *mut ::std::os::raw::c_void, + finalize_hint: *mut ::std::os::raw::c_void, + ), +>; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct napi_property_descriptor { + pub utf8name: *const ::std::os::raw::c_char, + pub name: napi_value, + pub method: napi_callback, + pub getter: napi_callback, + pub setter: napi_callback, + pub value: napi_value, + pub attributes: napi_property_attributes, + pub data: *mut ::std::os::raw::c_void, +} + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct napi_extended_error_info { + pub error_message: *const ::std::os::raw::c_char, + pub engine_reserved: *mut ::std::os::raw::c_void, + pub engine_error_code: u32, + pub error_code: napi_status, +} + +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum napi_key_collection_mode { + napi_key_include_prototypes, + napi_key_own_only, +} + +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum napi_key_filter { + napi_key_all_properties = 0, + napi_key_writable = 1, + napi_key_enumerable = 1 << 1, + napi_key_configurable = 1 << 2, + napi_key_skip_strings = 1 << 3, + napi_key_skip_symbols = 1 << 4, +} + +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum napi_key_conversion { + napi_key_keep_numbers, + napi_key_numbers_to_strings, +} + +extern "C" { + pub fn napi_get_last_error_info( + env: napi_env, + result: *mut *const napi_extended_error_info, + ) -> napi_status; +} +extern "C" { + pub fn napi_get_undefined(env: napi_env, result: *mut napi_value) -> napi_status; +} +extern "C" { + pub fn napi_get_null(env: napi_env, result: *mut napi_value) -> napi_status; +} +extern "C" { + pub fn napi_get_global(env: napi_env, result: *mut napi_value) -> napi_status; +} +extern "C" { + pub fn napi_get_boolean(env: napi_env, value: bool, result: *mut napi_value) -> napi_status; +} +extern "C" { + pub fn napi_create_object(env: napi_env, result: *mut napi_value) -> napi_status; +} +extern "C" { + pub fn napi_create_array(env: napi_env, result: *mut napi_value) -> napi_status; +} +extern "C" { + pub fn napi_create_array_with_length( + env: napi_env, + length: usize, + result: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_create_double(env: napi_env, value: f64, result: *mut napi_value) -> napi_status; +} +extern "C" { + pub fn napi_create_int32(env: napi_env, value: i32, result: *mut napi_value) -> napi_status; +} +extern "C" { + pub fn napi_create_uint32(env: napi_env, value: u32, result: *mut napi_value) -> napi_status; +} +extern "C" { + pub fn napi_create_int64(env: napi_env, value: i64, result: *mut napi_value) -> napi_status; +} +extern "C" { + pub fn napi_create_string_latin1( + env: napi_env, + str_: *const ::std::os::raw::c_char, + length: usize, + result: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_create_string_utf8( + env: napi_env, + str_: *const ::std::os::raw::c_char, + length: usize, + result: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_create_string_utf16( + env: napi_env, + str_: *const u16, + length: usize, + result: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_create_symbol( + env: napi_env, + description: napi_value, + result: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_create_function( + env: napi_env, + utf8name: *const ::std::os::raw::c_char, + length: usize, + cb: napi_callback, + data: *mut ::std::os::raw::c_void, + result: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_create_error( + env: napi_env, + code: napi_value, + msg: napi_value, + result: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_create_type_error( + env: napi_env, + code: napi_value, + msg: napi_value, + result: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_create_range_error( + env: napi_env, + code: napi_value, + msg: napi_value, + result: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_typeof(env: napi_env, value: napi_value, result: *mut napi_valuetype) -> napi_status; +} +extern "C" { + pub fn napi_get_value_double(env: napi_env, value: napi_value, result: *mut f64) -> napi_status; +} +extern "C" { + pub fn napi_get_value_int32(env: napi_env, value: napi_value, result: *mut i32) -> napi_status; +} +extern "C" { + pub fn napi_get_value_uint32(env: napi_env, value: napi_value, result: *mut u32) -> napi_status; +} +extern "C" { + pub fn napi_get_value_int64(env: napi_env, value: napi_value, result: *mut i64) -> napi_status; +} +extern "C" { + pub fn napi_get_value_bool(env: napi_env, value: napi_value, result: *mut bool) -> napi_status; +} +extern "C" { + pub fn napi_get_value_string_latin1( + env: napi_env, + value: napi_value, + buf: *mut ::std::os::raw::c_char, + bufsize: usize, + result: *mut usize, + ) -> napi_status; +} +extern "C" { + pub fn napi_get_value_string_utf8( + env: napi_env, + value: napi_value, + buf: *mut ::std::os::raw::c_char, + bufsize: usize, + result: *mut usize, + ) -> napi_status; +} +extern "C" { + pub fn napi_get_value_string_utf16( + env: napi_env, + value: napi_value, + buf: *mut u16, + bufsize: usize, + result: *mut usize, + ) -> napi_status; +} +extern "C" { + pub fn napi_coerce_to_bool( + env: napi_env, + value: napi_value, + result: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_coerce_to_number( + env: napi_env, + value: napi_value, + result: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_coerce_to_object( + env: napi_env, + value: napi_value, + result: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_coerce_to_string( + env: napi_env, + value: napi_value, + result: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_get_prototype( + env: napi_env, + object: napi_value, + result: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_get_property_names( + env: napi_env, + object: napi_value, + result: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_set_property( + env: napi_env, + object: napi_value, + key: napi_value, + value: napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_has_property( + env: napi_env, + object: napi_value, + key: napi_value, + result: *mut bool, + ) -> napi_status; +} +extern "C" { + pub fn napi_get_property( + env: napi_env, + object: napi_value, + key: napi_value, + result: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_delete_property( + env: napi_env, + object: napi_value, + key: napi_value, + result: *mut bool, + ) -> napi_status; +} +extern "C" { + pub fn napi_has_own_property( + env: napi_env, + object: napi_value, + key: napi_value, + result: *mut bool, + ) -> napi_status; +} +extern "C" { + pub fn napi_set_named_property( + env: napi_env, + object: napi_value, + utf8name: *const ::std::os::raw::c_char, + value: napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_has_named_property( + env: napi_env, + object: napi_value, + utf8name: *const ::std::os::raw::c_char, + result: *mut bool, + ) -> napi_status; +} +extern "C" { + pub fn napi_get_named_property( + env: napi_env, + object: napi_value, + utf8name: *const ::std::os::raw::c_char, + result: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_set_element( + env: napi_env, + object: napi_value, + index: u32, + value: napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_has_element( + env: napi_env, + object: napi_value, + index: u32, + result: *mut bool, + ) -> napi_status; +} +extern "C" { + pub fn napi_get_element( + env: napi_env, + object: napi_value, + index: u32, + result: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_delete_element( + env: napi_env, + object: napi_value, + index: u32, + result: *mut bool, + ) -> napi_status; +} +extern "C" { + pub fn napi_define_properties( + env: napi_env, + object: napi_value, + property_count: usize, + properties: *const napi_property_descriptor, + ) -> napi_status; +} +extern "C" { + pub fn napi_is_array(env: napi_env, value: napi_value, result: *mut bool) -> napi_status; +} +extern "C" { + pub fn napi_get_array_length(env: napi_env, value: napi_value, result: *mut u32) -> napi_status; +} +extern "C" { + pub fn napi_strict_equals( + env: napi_env, + lhs: napi_value, + rhs: napi_value, + result: *mut bool, + ) -> napi_status; +} +extern "C" { + pub fn napi_call_function( + env: napi_env, + recv: napi_value, + func: napi_value, + argc: usize, + argv: *const napi_value, + result: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_new_instance( + env: napi_env, + constructor: napi_value, + argc: usize, + argv: *const napi_value, + result: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_instanceof( + env: napi_env, + object: napi_value, + constructor: napi_value, + result: *mut bool, + ) -> napi_status; +} +extern "C" { + pub fn napi_get_cb_info( + env: napi_env, + cbinfo: napi_callback_info, + argc: *mut usize, + argv: *mut napi_value, + this_arg: *mut napi_value, + data: *mut *mut ::std::os::raw::c_void, + ) -> napi_status; +} +extern "C" { + pub fn napi_get_new_target( + env: napi_env, + cbinfo: napi_callback_info, + result: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_define_class( + env: napi_env, + utf8name: *const ::std::os::raw::c_char, + length: usize, + constructor: napi_callback, + data: *mut ::std::os::raw::c_void, + property_count: usize, + properties: *const napi_property_descriptor, + result: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_wrap( + env: napi_env, + js_object: napi_value, + native_object: *mut ::std::os::raw::c_void, + finalize_cb: napi_finalize, + finalize_hint: *mut ::std::os::raw::c_void, + result: *mut napi_ref, + ) -> napi_status; +} +extern "C" { + pub fn napi_unwrap( + env: napi_env, + js_object: napi_value, + result: *mut *mut ::std::os::raw::c_void, + ) -> napi_status; +} +extern "C" { + pub fn napi_remove_wrap( + env: napi_env, + js_object: napi_value, + result: *mut *mut ::std::os::raw::c_void, + ) -> napi_status; +} +extern "C" { + pub fn napi_create_external( + env: napi_env, + data: *mut ::std::os::raw::c_void, + finalize_cb: napi_finalize, + finalize_hint: *mut ::std::os::raw::c_void, + result: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_get_value_external( + env: napi_env, + value: napi_value, + result: *mut *mut ::std::os::raw::c_void, + ) -> napi_status; +} +extern "C" { + pub fn napi_create_reference( + env: napi_env, + value: napi_value, + initial_refcount: u32, + result: *mut napi_ref, + ) -> napi_status; +} +extern "C" { + pub fn napi_delete_reference(env: napi_env, ref_: napi_ref) -> napi_status; +} +extern "C" { + pub fn napi_reference_ref(env: napi_env, ref_: napi_ref, result: *mut u32) -> napi_status; +} +extern "C" { + pub fn napi_reference_unref(env: napi_env, ref_: napi_ref, result: *mut u32) -> napi_status; +} +extern "C" { + pub fn napi_get_reference_value( + env: napi_env, + ref_: napi_ref, + result: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_open_handle_scope(env: napi_env, result: *mut napi_handle_scope) -> napi_status; +} +extern "C" { + pub fn napi_close_handle_scope(env: napi_env, scope: napi_handle_scope) -> napi_status; +} +extern "C" { + pub fn napi_open_escapable_handle_scope( + env: napi_env, + result: *mut napi_escapable_handle_scope, + ) -> napi_status; +} +extern "C" { + pub fn napi_close_escapable_handle_scope( + env: napi_env, + scope: napi_escapable_handle_scope, + ) -> napi_status; +} +extern "C" { + pub fn napi_escape_handle( + env: napi_env, + scope: napi_escapable_handle_scope, + escapee: napi_value, + result: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_throw(env: napi_env, error: napi_value) -> napi_status; +} +extern "C" { + pub fn napi_throw_error( + env: napi_env, + code: *const ::std::os::raw::c_char, + msg: *const ::std::os::raw::c_char, + ) -> napi_status; +} +extern "C" { + pub fn napi_throw_type_error( + env: napi_env, + code: *const ::std::os::raw::c_char, + msg: *const ::std::os::raw::c_char, + ) -> napi_status; +} +extern "C" { + pub fn napi_throw_range_error( + env: napi_env, + code: *const ::std::os::raw::c_char, + msg: *const ::std::os::raw::c_char, + ) -> napi_status; +} +extern "C" { + pub fn napi_is_error(env: napi_env, value: napi_value, result: *mut bool) -> napi_status; +} +extern "C" { + pub fn napi_is_exception_pending(env: napi_env, result: *mut bool) -> napi_status; +} +extern "C" { + pub fn napi_get_and_clear_last_exception(env: napi_env, result: *mut napi_value) -> napi_status; +} +extern "C" { + pub fn napi_is_arraybuffer(env: napi_env, value: napi_value, result: *mut bool) -> napi_status; +} +extern "C" { + pub fn napi_create_arraybuffer( + env: napi_env, + byte_length: usize, + data: *mut *mut ::std::os::raw::c_void, + result: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_create_external_arraybuffer( + env: napi_env, + external_data: *mut ::std::os::raw::c_void, + byte_length: usize, + finalize_cb: napi_finalize, + finalize_hint: *mut ::std::os::raw::c_void, + result: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_get_arraybuffer_info( + env: napi_env, + arraybuffer: napi_value, + data: *mut *mut ::std::os::raw::c_void, + byte_length: *mut usize, + ) -> napi_status; +} +extern "C" { + pub fn napi_is_typedarray(env: napi_env, value: napi_value, result: *mut bool) -> napi_status; +} +extern "C" { + pub fn napi_create_typedarray( + env: napi_env, + type_: napi_typedarray_type, + length: usize, + arraybuffer: napi_value, + byte_offset: usize, + result: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_get_typedarray_info( + env: napi_env, + typedarray: napi_value, + type_: *mut napi_typedarray_type, + length: *mut usize, + data: *mut *mut ::std::os::raw::c_void, + arraybuffer: *mut napi_value, + byte_offset: *mut usize, + ) -> napi_status; +} +extern "C" { + pub fn napi_create_dataview( + env: napi_env, + length: usize, + arraybuffer: napi_value, + byte_offset: usize, + result: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_is_dataview(env: napi_env, value: napi_value, result: *mut bool) -> napi_status; +} +extern "C" { + pub fn napi_get_dataview_info( + env: napi_env, + dataview: napi_value, + bytelength: *mut usize, + data: *mut *mut ::std::os::raw::c_void, + arraybuffer: *mut napi_value, + byte_offset: *mut usize, + ) -> napi_status; +} +extern "C" { + pub fn napi_get_version(env: napi_env, result: *mut u32) -> napi_status; +} +extern "C" { + pub fn napi_create_promise( + env: napi_env, + deferred: *mut napi_deferred, + promise: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_resolve_deferred( + env: napi_env, + deferred: napi_deferred, + resolution: napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_reject_deferred( + env: napi_env, + deferred: napi_deferred, + rejection: napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_is_promise(env: napi_env, value: napi_value, is_promise: *mut bool) -> napi_status; +} +extern "C" { + pub fn napi_run_script(env: napi_env, script: napi_value, result: *mut napi_value) + -> napi_status; +} +extern "C" { + pub fn napi_adjust_external_memory( + env: napi_env, + change_in_bytes: i64, + adjusted_value: *mut i64, + ) -> napi_status; +} + +#[cfg(feature = "napi5")] +extern "C" { + pub fn napi_create_date(env: napi_env, time: f64, result: *mut napi_value) -> napi_status; +} + +#[cfg(feature = "napi5")] +extern "C" { + pub fn napi_is_date(env: napi_env, value: napi_value, is_date: *mut bool) -> napi_status; +} + +#[cfg(feature = "napi5")] +extern "C" { + pub fn napi_get_date_value(env: napi_env, value: napi_value, result: *mut f64) -> napi_status; +} + +#[cfg(feature = "napi5")] +extern "C" { + pub fn napi_add_finalizer( + env: napi_env, + js_object: napi_value, + native_object: *mut ::std::os::raw::c_void, + finalize_cb: napi_finalize, + finalize_hint: *mut ::std::os::raw::c_void, + result: *mut napi_ref, + ) -> napi_status; +} + +#[cfg(feature = "napi6")] +extern "C" { + pub fn napi_create_bigint_int64( + env: napi_env, + value: i64, + result: *mut napi_value, + ) -> napi_status; +} + +#[cfg(feature = "napi6")] +extern "C" { + pub fn napi_create_bigint_uint64( + env: napi_env, + value: u64, + result: *mut napi_value, + ) -> napi_status; +} + +#[cfg(feature = "napi6")] +extern "C" { + pub fn napi_create_bigint_words( + env: napi_env, + sign_bit: ::std::os::raw::c_int, + word_count: usize, + words: *const u64, + result: *mut napi_value, + ) -> napi_status; +} + +#[cfg(feature = "napi6")] +extern "C" { + pub fn napi_get_value_bigint_int64( + env: napi_env, + value: napi_value, + result: *mut i64, + lossless: *mut bool, + ) -> napi_status; +} + +#[cfg(feature = "napi6")] +extern "C" { + pub fn napi_get_value_bigint_uint64( + env: napi_env, + value: napi_value, + result: *mut u64, + lossless: *mut bool, + ) -> napi_status; +} + +#[cfg(feature = "napi6")] +extern "C" { + pub fn napi_get_value_bigint_words( + env: napi_env, + value: napi_value, + sign_bit: *mut ::std::os::raw::c_int, + word_count: *mut usize, + words: *mut u64, + ) -> napi_status; +} + +#[cfg(feature = "napi6")] +extern "C" { + pub fn napi_get_all_property_names( + env: napi_env, + object: napi_value, + key_mode: napi_key_collection_mode, + key_filter: napi_key_filter, + key_conversion: napi_key_conversion, + result: *mut napi_value, + ) -> napi_status; +} + +#[cfg(feature = "napi6")] +extern "C" { + pub fn napi_set_instance_data( + env: napi_env, + data: *mut ::std::os::raw::c_void, + finalize_cb: napi_finalize, + finalize_hint: *mut ::std::os::raw::c_void, + ) -> napi_status; +} + +#[cfg(feature = "napi6")] +extern "C" { + pub fn napi_get_instance_data( + env: napi_env, + data: *mut *mut ::std::os::raw::c_void, + ) -> napi_status; +} + +#[cfg(feature = "napi7")] +extern "C" { + pub fn napi_detach_arraybuffer(env: napi_env, arraybuffer: napi_value) -> napi_status; +} + +#[cfg(feature = "napi7")] +extern "C" { + pub fn napi_is_detached_arraybuffer( + env: napi_env, + value: napi_value, + result: *mut bool, + ) -> napi_status; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct napi_callback_scope__ { + _unused: [u8; 0], +} +pub type napi_callback_scope = *mut napi_callback_scope__; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct napi_async_context__ { + _unused: [u8; 0], +} +pub type napi_async_context = *mut napi_async_context__; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct napi_async_work__ { + _unused: [u8; 0], +} +pub type napi_async_work = *mut napi_async_work__; + +#[cfg(feature = "napi4")] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct napi_threadsafe_function__ { + _unused: [u8; 0], +} + +#[cfg(feature = "napi4")] +pub type napi_threadsafe_function = *mut napi_threadsafe_function__; + +#[cfg(feature = "napi4")] +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum napi_threadsafe_function_release_mode { + napi_tsfn_release, + napi_tsfn_abort, +} + +#[cfg(feature = "napi4")] +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum napi_threadsafe_function_call_mode { + napi_tsfn_nonblocking, + napi_tsfn_blocking, +} + +pub type napi_async_execute_callback = + ::std::option::Option; +pub type napi_async_complete_callback = ::std::option::Option< + unsafe extern "C" fn(env: napi_env, status: napi_status, data: *mut ::std::os::raw::c_void), +>; + +#[cfg(feature = "napi4")] +pub type napi_threadsafe_function_call_js = ::std::option::Option< + unsafe extern "C" fn( + env: napi_env, + js_callback: napi_value, + context: *mut ::std::os::raw::c_void, + data: *mut ::std::os::raw::c_void, + ), +>; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct napi_node_version { + pub major: u32, + pub minor: u32, + pub patch: u32, + pub release: *const ::std::os::raw::c_char, +} + +pub type napi_addon_register_func = + ::std::option::Option napi_value>; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct napi_module { + pub nm_version: ::std::os::raw::c_int, + pub nm_flags: ::std::os::raw::c_uint, + pub nm_filename: *const ::std::os::raw::c_char, + pub nm_register_func: napi_addon_register_func, + pub nm_modname: *const ::std::os::raw::c_char, + pub nm_priv: *mut ::std::os::raw::c_void, + pub reserved: [*mut ::std::os::raw::c_void; 4usize], +} + +extern "C" { + pub fn napi_module_register(mod_: *mut napi_module); +} +extern "C" { + pub fn napi_fatal_error( + location: *const ::std::os::raw::c_char, + location_len: usize, + message: *const ::std::os::raw::c_char, + message_len: usize, + ); +} +extern "C" { + pub fn napi_async_init( + env: napi_env, + async_resource: napi_value, + async_resource_name: napi_value, + result: *mut napi_async_context, + ) -> napi_status; +} +extern "C" { + pub fn napi_async_destroy(env: napi_env, async_context: napi_async_context) -> napi_status; +} +extern "C" { + pub fn napi_make_callback( + env: napi_env, + async_context: napi_async_context, + recv: napi_value, + func: napi_value, + argc: usize, + argv: *const napi_value, + result: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_create_buffer( + env: napi_env, + length: usize, + data: *mut *mut ::std::os::raw::c_void, + result: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_create_external_buffer( + env: napi_env, + length: usize, + data: *mut ::std::os::raw::c_void, + finalize_cb: napi_finalize, + finalize_hint: *mut ::std::os::raw::c_void, + result: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_create_buffer_copy( + env: napi_env, + length: usize, + data: *const ::std::os::raw::c_void, + result_data: *mut *mut ::std::os::raw::c_void, + result: *mut napi_value, + ) -> napi_status; +} +extern "C" { + pub fn napi_is_buffer(env: napi_env, value: napi_value, result: *mut bool) -> napi_status; +} +extern "C" { + pub fn napi_get_buffer_info( + env: napi_env, + value: napi_value, + data: *mut *mut ::std::os::raw::c_void, + length: *mut usize, + ) -> napi_status; +} +extern "C" { + pub fn napi_create_async_work( + env: napi_env, + async_resource: napi_value, + async_resource_name: napi_value, + execute: napi_async_execute_callback, + complete: napi_async_complete_callback, + data: *mut ::std::os::raw::c_void, + result: *mut napi_async_work, + ) -> napi_status; +} +extern "C" { + pub fn napi_delete_async_work(env: napi_env, work: napi_async_work) -> napi_status; +} +extern "C" { + pub fn napi_queue_async_work(env: napi_env, work: napi_async_work) -> napi_status; +} +extern "C" { + pub fn napi_cancel_async_work(env: napi_env, work: napi_async_work) -> napi_status; +} +extern "C" { + pub fn napi_get_node_version( + env: napi_env, + version: *mut *const napi_node_version, + ) -> napi_status; +} + +#[cfg(feature = "napi2")] +extern "C" { + pub fn napi_get_uv_event_loop(env: napi_env, loop_: *mut *mut uv_loop_s) -> napi_status; +} + +#[cfg(feature = "napi3")] +extern "C" { + pub fn napi_fatal_exception(env: napi_env, err: napi_value) -> napi_status; +} +#[cfg(feature = "napi3")] +extern "C" { + pub fn napi_add_env_cleanup_hook( + env: napi_env, + fun: ::std::option::Option, + arg: *mut ::std::os::raw::c_void, + ) -> napi_status; +} +#[cfg(feature = "napi3")] +extern "C" { + pub fn napi_remove_env_cleanup_hook( + env: napi_env, + fun: ::std::option::Option, + arg: *mut ::std::os::raw::c_void, + ) -> napi_status; +} +#[cfg(feature = "napi3")] +extern "C" { + pub fn napi_open_callback_scope( + env: napi_env, + resource_object: napi_value, + context: napi_async_context, + result: *mut napi_callback_scope, + ) -> napi_status; +} +#[cfg(feature = "napi3")] +extern "C" { + pub fn napi_close_callback_scope(env: napi_env, scope: napi_callback_scope) -> napi_status; +} + +#[cfg(feature = "napi4")] +extern "C" { + pub fn napi_create_threadsafe_function( + env: napi_env, + func: napi_value, + async_resource: napi_value, + async_resource_name: napi_value, + max_queue_size: usize, + initial_thread_count: usize, + thread_finalize_data: *mut ::std::os::raw::c_void, + thread_finalize_cb: napi_finalize, + context: *mut ::std::os::raw::c_void, + call_js_cb: napi_threadsafe_function_call_js, + result: *mut napi_threadsafe_function, + ) -> napi_status; +} +#[cfg(feature = "napi4")] +extern "C" { + pub fn napi_get_threadsafe_function_context( + func: napi_threadsafe_function, + result: *mut *mut ::std::os::raw::c_void, + ) -> napi_status; +} +#[cfg(feature = "napi4")] +extern "C" { + pub fn napi_call_threadsafe_function( + func: napi_threadsafe_function, + data: *mut ::std::os::raw::c_void, + is_blocking: napi_threadsafe_function_call_mode, + ) -> napi_status; +} +#[cfg(feature = "napi4")] +extern "C" { + pub fn napi_acquire_threadsafe_function(func: napi_threadsafe_function) -> napi_status; +} +#[cfg(feature = "napi4")] +extern "C" { + pub fn napi_release_threadsafe_function( + func: napi_threadsafe_function, + mode: napi_threadsafe_function_release_mode, + ) -> napi_status; +} +#[cfg(feature = "napi4")] +extern "C" { + pub fn napi_unref_threadsafe_function( + env: napi_env, + func: napi_threadsafe_function, + ) -> napi_status; +} +#[cfg(feature = "napi4")] +extern "C" { + pub fn napi_ref_threadsafe_function(env: napi_env, func: napi_threadsafe_function) + -> napi_status; +} diff --git a/sys/src/sys.rs b/sys/src/sys.rs deleted file mode 100644 index cd503e4b..00000000 --- a/sys/src/sys.rs +++ /dev/null @@ -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")); diff --git a/test_module/Cargo.toml b/test_module/Cargo.toml index 80c7d7a6..e44734a9 100644 --- a/test_module/Cargo.toml +++ b/test_module/Cargo.toml @@ -7,9 +7,13 @@ version = "0.1.0" [lib] crate-type = ["cdylib"] +[features] +latest = ["napi/napi7"] +napi3 = ["napi/napi3"] + [dependencies] 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"} serde = "1" serde_bytes = "0.11" diff --git a/test_module/__test__/napi4/uv.spec.ts b/test_module/__test__/napi4/uv.spec.ts deleted file mode 100644 index b13c2e8d..00000000 --- a/test_module/__test__/napi4/uv.spec.ts +++ /dev/null @@ -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) - }) -} diff --git a/test_module/__test__/napi4/uv_worker.js b/test_module/__test__/napi4/uv_worker.js deleted file mode 100644 index db2945c7..00000000 --- a/test_module/__test__/napi4/uv_worker.js +++ /dev/null @@ -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 - }) -} diff --git a/test_module/package.json b/test_module/package.json index 24684379..9e3c1605 100644 --- a/test_module/package.json +++ b/test_module/package.json @@ -2,9 +2,11 @@ "name": "test-module", "version": "1.0.0", "scripts": { - "build": "cargo build && 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-release": "cargo build --release && node ../scripts/index.js build --release", + "build": "cargo build --features \"latest\" && node ../scripts/index.js build", + "build-napi3": "cargo build --features \"napi3\" && node ../scripts/index.js build", + "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" } } diff --git a/test_module/src/lib.rs b/test_module/src/lib.rs index 48617ca2..889cb952 100644 --- a/test_module/src/lib.rs +++ b/test_module/src/lib.rs @@ -7,17 +7,14 @@ extern crate serde_derive; use napi::{Module, Result}; -#[cfg(napi3)] mod cleanup_env; -#[cfg(napi4)] -mod libuv; -#[cfg(napi4)] +#[cfg(feature = "latest")] mod napi4; -#[cfg(napi5)] +#[cfg(feature = "latest")] mod napi5; -#[cfg(napi6)] +#[cfg(feature = "latest")] mod napi6; -#[cfg(napi4)] +#[cfg(feature = "latest")] mod tokio_rt; mod array; @@ -58,17 +55,14 @@ fn init(module: &mut Module) -> Result<()> { env::register_js(module)?; object::register_js(module)?; global::register_js(module)?; - #[cfg(napi3)] cleanup_env::register_js(module)?; - #[cfg(napi4)] + #[cfg(feature = "latest")] napi4::register_js(module)?; - #[cfg(napi4)] + #[cfg(feature = "latest")] tokio_rt::register_js(module)?; - #[cfg(napi4)] - libuv::read_file::register_js(module)?; - #[cfg(napi5)] + #[cfg(feature = "latest")] napi5::register_js(module)?; - #[cfg(napi6)] + #[cfg(feature = "latest")] napi6::register_js(module)?; Ok(()) } diff --git a/test_module/src/libuv/mod.rs b/test_module/src/libuv/mod.rs deleted file mode 100644 index 1cbe4ba6..00000000 --- a/test_module/src/libuv/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod read_file; diff --git a/test_module/src/libuv/read_file.rs b/test_module/src/libuv/read_file.rs deleted file mode 100644 index 5f0537f2..00000000 --- a/test_module/src/libuv/read_file.rs +++ /dev/null @@ -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 { - let path = ctx.get::(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(()) -}