feat(napi,sys): implement Symbol.for (#1721)
Co-authored-by: LongYinan <lynweklm@gmail.com>
This commit is contained in:
parent
c853a412b6
commit
3418fd3e8f
13 changed files with 89 additions and 7 deletions
|
@ -26,7 +26,7 @@ compat-mode = []
|
|||
default = ["napi3", "compat-mode"] # for most Node.js users
|
||||
experimental = ["napi-sys/experimental"]
|
||||
chrono_date = ["chrono", "napi5"]
|
||||
full = ["latin1", "napi8", "async", "serde-json", "experimental", "chrono_date"]
|
||||
full = ["latin1", "napi9", "async", "serde-json", "experimental", "chrono_date"]
|
||||
latin1 = ["encoding_rs"]
|
||||
error_anyhow = ["anyhow"]
|
||||
napi1 = []
|
||||
|
@ -37,6 +37,7 @@ napi5 = ["napi4", "napi-sys/napi5"]
|
|||
napi6 = ["napi5", "napi-sys/napi6"]
|
||||
napi7 = ["napi6", "napi-sys/napi7"]
|
||||
napi8 = ["napi7", "napi-sys/napi8"]
|
||||
napi9 = ["napi8", "napi-sys/napi9"]
|
||||
serde-json = ["serde", "serde_json"]
|
||||
tokio_fs = ["tokio/fs"]
|
||||
tokio_full = ["tokio/full"]
|
||||
|
|
|
@ -6,6 +6,8 @@ use super::{FromNapiValue, ToNapiValue, TypeName, ValidateNapiValue};
|
|||
|
||||
pub struct Symbol {
|
||||
desc: Option<String>,
|
||||
#[cfg(feature = "napi9")]
|
||||
for_desc: Option<String>,
|
||||
}
|
||||
|
||||
impl TypeName for Symbol {
|
||||
|
@ -22,17 +24,43 @@ impl ValidateNapiValue for Symbol {}
|
|||
|
||||
impl Symbol {
|
||||
pub fn new(desc: String) -> Self {
|
||||
Self { desc: Some(desc) }
|
||||
Self {
|
||||
desc: Some(desc),
|
||||
#[cfg(feature = "napi9")]
|
||||
for_desc: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn identity() -> Self {
|
||||
Self { desc: None }
|
||||
Self {
|
||||
desc: None,
|
||||
#[cfg(feature = "napi9")]
|
||||
for_desc: None,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "napi9")]
|
||||
pub fn for_desc(desc: String) -> Self {
|
||||
Self {
|
||||
desc: None,
|
||||
for_desc: Some(desc.to_owned()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToNapiValue for Symbol {
|
||||
unsafe fn to_napi_value(env: sys::napi_env, val: Self) -> crate::Result<sys::napi_value> {
|
||||
let mut symbol_value = ptr::null_mut();
|
||||
#[cfg(feature = "napi9")]
|
||||
if let Some(desc) = val.for_desc {
|
||||
check_status!(
|
||||
unsafe {
|
||||
sys::node_api_symbol_for(env, desc.as_ptr().cast(), desc.len(), &mut symbol_value)
|
||||
},
|
||||
"Failed to call node_api_symbol_for"
|
||||
)?;
|
||||
return Ok(symbol_value);
|
||||
}
|
||||
check_status!(unsafe {
|
||||
sys::napi_create_symbol(
|
||||
env,
|
||||
|
@ -63,6 +91,10 @@ impl FromNapiValue for Symbol {
|
|||
_env: sys::napi_env,
|
||||
_napi_val: sys::napi_value,
|
||||
) -> crate::Result<Self> {
|
||||
Ok(Self { desc: None })
|
||||
Ok(Self {
|
||||
desc: None,
|
||||
#[cfg(feature = "napi9")]
|
||||
for_desc: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1250,6 +1250,18 @@ impl Env {
|
|||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "napi9")]
|
||||
pub fn symbol_for(&self, description: &str) -> Result<JsSymbol> {
|
||||
let mut result = ptr::null_mut();
|
||||
let len = description.len();
|
||||
let description = CString::new(description)?;
|
||||
check_status!(unsafe {
|
||||
sys::node_api_symbol_for(self.0, description.as_ptr(), len, &mut result)
|
||||
})?;
|
||||
|
||||
Ok(unsafe { JsSymbol::from_raw_unchecked(self.0, result) })
|
||||
}
|
||||
|
||||
/// ### Serialize `Rust Struct` into `JavaScript Value`
|
||||
///
|
||||
/// ```
|
||||
|
|
|
@ -21,6 +21,7 @@ napi5 = ["napi4"]
|
|||
napi6 = ["napi5"]
|
||||
napi7 = ["napi6"]
|
||||
napi8 = ["napi7"]
|
||||
napi9 = ["napi8"]
|
||||
|
||||
[package.metadata.workspaces]
|
||||
independent = true
|
||||
|
|
|
@ -698,6 +698,24 @@ mod napi8 {
|
|||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "napi9")]
|
||||
mod napi9 {
|
||||
use std::os::raw::c_char;
|
||||
|
||||
use super::super::types::*;
|
||||
|
||||
generate!(
|
||||
extern "C" {
|
||||
fn node_api_symbol_for(
|
||||
env: napi_env,
|
||||
utf8name: *const c_char,
|
||||
length: usize,
|
||||
result: *mut napi_value,
|
||||
) -> napi_status;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "experimental")]
|
||||
mod experimental {
|
||||
use std::os::raw::c_char;
|
||||
|
@ -739,6 +757,8 @@ pub use napi6::*;
|
|||
pub use napi7::*;
|
||||
#[cfg(feature = "napi8")]
|
||||
pub use napi8::*;
|
||||
#[cfg(feature = "napi9")]
|
||||
pub use napi9::*;
|
||||
|
||||
#[cfg(windows)]
|
||||
pub(super) unsafe fn load() -> Result<libloading::Library, libloading::Error> {
|
||||
|
|
|
@ -9,7 +9,7 @@ version = "0.1.0"
|
|||
crate-type = ["cdylib"]
|
||||
|
||||
[features]
|
||||
latest = ["napi/napi8"]
|
||||
latest = ["napi/napi9"]
|
||||
napi3 = ["napi/napi3"]
|
||||
|
||||
[dependencies]
|
||||
|
|
|
@ -16,7 +16,7 @@ chrono = "0.4"
|
|||
futures = "0.3"
|
||||
napi = { path = "../../crates/napi", default-features = false, features = [
|
||||
"tokio_fs",
|
||||
"napi8",
|
||||
"napi9",
|
||||
"tokio_rt",
|
||||
"serde-json",
|
||||
"async",
|
||||
|
|
|
@ -308,6 +308,8 @@ Generated by [AVA](https://avajs.dev).
|
|||
␊
|
||||
export function createSymbol(): symbol␊
|
||||
␊
|
||||
export function createSymbolFor(desc: string): symbol␊
|
||||
␊
|
||||
/** You could break the step and for an new continuous value. */␊
|
||||
export const enum CustomNumEnum {␊
|
||||
One = 1,␊
|
||||
|
|
Binary file not shown.
|
@ -62,6 +62,7 @@ import {
|
|||
getNull,
|
||||
setSymbolInObj,
|
||||
createSymbol,
|
||||
createSymbolFor,
|
||||
threadsafeFunctionFatalMode,
|
||||
createExternal,
|
||||
getExternal,
|
||||
|
@ -997,3 +998,9 @@ Napi5Test('Date from chrono::NativeDateTime test', (t) => {
|
|||
t.true(fixture instanceof Date)
|
||||
t.is(fixture?.toISOString(), '2016-12-23T15:25:59.325Z')
|
||||
})
|
||||
|
||||
const Napi9Test = Number(process.versions.napi) >= 9 ? test : test.skip
|
||||
|
||||
Napi9Test('create symbol for', (t) => {
|
||||
t.is(createSymbolFor('foo'), Symbol.for('foo'))
|
||||
})
|
||||
|
|
2
examples/napi/index.d.ts
vendored
2
examples/napi/index.d.ts
vendored
|
@ -298,6 +298,8 @@ export function createObjWithProperty(): { value: ArrayBuffer, get getter(): num
|
|||
|
||||
export function createSymbol(): symbol
|
||||
|
||||
export function createSymbolFor(desc: string): symbol
|
||||
|
||||
/** You could break the step and for an new continuous value. */
|
||||
export const enum CustomNumEnum {
|
||||
One = 1,
|
||||
|
|
|
@ -11,3 +11,8 @@ pub fn set_symbol_in_obj(env: Env, symbol: JsSymbol) -> Result<JsObject> {
|
|||
pub fn create_symbol() -> Symbol {
|
||||
Symbol::new("a symbol".to_owned())
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn create_symbol_for(desc: String) -> Symbol {
|
||||
Symbol::for_desc(desc)
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
"format:rs": "cargo fmt",
|
||||
"format:toml": "taplo format",
|
||||
"lint": "eslint -c .eslintrc.yml .",
|
||||
"test": "lerna run test --ignore @napi-rs/cli",
|
||||
"test": "lerna run test --concurrency=1 --ignore @napi-rs/cli",
|
||||
"test:cli": "yarn workspace @napi-rs/cli test",
|
||||
"test:electron": "electron examples/napi/electron.js",
|
||||
"test:macro": "cargo test -p napi-examples",
|
||||
|
|
Loading…
Reference in a new issue