feat(napi): improve symbol support
This commit is contained in:
parent
c0a89834c2
commit
424c7805c4
10 changed files with 101 additions and 29 deletions
|
@ -30,7 +30,9 @@ pub trait ToTypeDef {
|
||||||
static KNOWN_TYPES: Lazy<HashMap<&'static str, &'static str>> = Lazy::new(|| {
|
static KNOWN_TYPES: Lazy<HashMap<&'static str, &'static str>> = Lazy::new(|| {
|
||||||
let mut map = HashMap::default();
|
let mut map = HashMap::default();
|
||||||
map.extend([
|
map.extend([
|
||||||
|
("JsUndefined", "undefined"),
|
||||||
("()", "undefined"),
|
("()", "undefined"),
|
||||||
|
("JsNumber", "number"),
|
||||||
("i8", "number"),
|
("i8", "number"),
|
||||||
("i16", "number"),
|
("i16", "number"),
|
||||||
("i32", "number"),
|
("i32", "number"),
|
||||||
|
@ -47,12 +49,15 @@ static KNOWN_TYPES: Lazy<HashMap<&'static str, &'static str>> = Lazy::new(|| {
|
||||||
("isize", "BigInt"),
|
("isize", "BigInt"),
|
||||||
("JsBigInt", "BigInt"),
|
("JsBigInt", "BigInt"),
|
||||||
("BigInt", "BigInt"),
|
("BigInt", "BigInt"),
|
||||||
|
("JsBoolean", "boolean"),
|
||||||
("bool", "boolean"),
|
("bool", "boolean"),
|
||||||
|
("JsString", "string"),
|
||||||
("String", "string"),
|
("String", "string"),
|
||||||
("str", "string"),
|
("str", "string"),
|
||||||
("Latin1String", "string"),
|
("Latin1String", "string"),
|
||||||
("Utf16String", "string"),
|
("Utf16String", "string"),
|
||||||
("char", "string"),
|
("char", "string"),
|
||||||
|
("JsObject", "object"),
|
||||||
("Object", "object"),
|
("Object", "object"),
|
||||||
("Value", "any"),
|
("Value", "any"),
|
||||||
("Map", "Record<string, any>"),
|
("Map", "Record<string, any>"),
|
||||||
|
@ -71,7 +76,8 @@ static KNOWN_TYPES: Lazy<HashMap<&'static str, &'static str>> = Lazy::new(|| {
|
||||||
("Either5", "{} | {} | {} | {} | {}"),
|
("Either5", "{} | {} | {} | {} | {}"),
|
||||||
("unknown", "unknown"),
|
("unknown", "unknown"),
|
||||||
("null", "null"),
|
("null", "null"),
|
||||||
("symbol", "symbol"),
|
("Symbol", "symbol"),
|
||||||
|
("JsSymbol", "symbol"),
|
||||||
("external", "object"),
|
("external", "object"),
|
||||||
("AbortSignal", "AbortSignal"),
|
("AbortSignal", "AbortSignal"),
|
||||||
("JsFunction", "(...args: any[]) => any"),
|
("JsFunction", "(...args: any[]) => any"),
|
||||||
|
|
|
@ -17,6 +17,7 @@ mod promise;
|
||||||
#[cfg(feature = "serde-json")]
|
#[cfg(feature = "serde-json")]
|
||||||
mod serde;
|
mod serde;
|
||||||
mod string;
|
mod string;
|
||||||
|
mod symbol;
|
||||||
mod task;
|
mod task;
|
||||||
|
|
||||||
pub use array::*;
|
pub use array::*;
|
||||||
|
@ -30,6 +31,7 @@ pub use nil::*;
|
||||||
pub use object::*;
|
pub use object::*;
|
||||||
pub use promise::*;
|
pub use promise::*;
|
||||||
pub use string::*;
|
pub use string::*;
|
||||||
|
pub use symbol::*;
|
||||||
pub use task::*;
|
pub use task::*;
|
||||||
|
|
||||||
#[cfg(feature = "latin1")]
|
#[cfg(feature = "latin1")]
|
||||||
|
|
48
crates/napi/src/bindgen_runtime/js_values/symbol.rs
Normal file
48
crates/napi/src/bindgen_runtime/js_values/symbol.rs
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
use std::{ffi::CString, ptr};
|
||||||
|
|
||||||
|
use crate::check_status;
|
||||||
|
|
||||||
|
use super::ToNapiValue;
|
||||||
|
|
||||||
|
pub struct Symbol {
|
||||||
|
desc: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Symbol {
|
||||||
|
pub fn new(desc: String) -> Self {
|
||||||
|
Self { desc: Some(desc) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn identity() -> Self {
|
||||||
|
Self { desc: None }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToNapiValue for Symbol {
|
||||||
|
unsafe fn to_napi_value(
|
||||||
|
env: napi_sys::napi_env,
|
||||||
|
val: Self,
|
||||||
|
) -> crate::Result<napi_sys::napi_value> {
|
||||||
|
let mut symbol_value = ptr::null_mut();
|
||||||
|
check_status!(napi_sys::napi_create_symbol(
|
||||||
|
env,
|
||||||
|
match val.desc {
|
||||||
|
Some(desc) => {
|
||||||
|
let mut desc_string = ptr::null_mut();
|
||||||
|
let desc_len = desc.len();
|
||||||
|
let desc_c_string = CString::new(desc)?;
|
||||||
|
check_status!(napi_sys::napi_create_string_utf8(
|
||||||
|
env,
|
||||||
|
desc_c_string.as_ptr(),
|
||||||
|
desc_len,
|
||||||
|
&mut desc_string
|
||||||
|
))?;
|
||||||
|
desc_string
|
||||||
|
}
|
||||||
|
None => ptr::null_mut(),
|
||||||
|
},
|
||||||
|
&mut symbol_value
|
||||||
|
))?;
|
||||||
|
Ok(symbol_value)
|
||||||
|
}
|
||||||
|
}
|
|
@ -260,12 +260,13 @@ macro_rules! impl_js_value_methods {
|
||||||
macro_rules! impl_object_methods {
|
macro_rules! impl_object_methods {
|
||||||
($js_value:ident) => {
|
($js_value:ident) => {
|
||||||
impl $js_value {
|
impl $js_value {
|
||||||
pub fn set_property<V>(&mut self, key: JsString, value: V) -> Result<()>
|
pub fn set_property<K, V>(&mut self, key: K, value: V) -> Result<()>
|
||||||
where
|
where
|
||||||
|
K: NapiRaw,
|
||||||
V: NapiRaw,
|
V: NapiRaw,
|
||||||
{
|
{
|
||||||
check_status!(unsafe {
|
check_status!(unsafe {
|
||||||
sys::napi_set_property(self.0.env, self.0.value, key.0.value, value.raw())
|
sys::napi_set_property(self.0.env, self.0.value, key.raw(), value.raw())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ Generated by [AVA](https://avajs.dev).
|
||||||
export function listObjKeys(obj: object): Array<string>␊
|
export function listObjKeys(obj: object): Array<string>␊
|
||||||
export function createObj(): object␊
|
export function createObj(): object␊
|
||||||
export function getGlobal(): typeof global␊
|
export function getGlobal(): typeof global␊
|
||||||
export function getUndefined(): JsUndefined␊
|
export function getUndefined(): void␊
|
||||||
export function getNull(): JsNull␊
|
export function getNull(): JsNull␊
|
||||||
export function asyncPlus100(p: Promise<number>): Promise<number>␊
|
export function asyncPlus100(p: Promise<number>): Promise<number>␊
|
||||||
interface PackageJson {␊
|
interface PackageJson {␊
|
||||||
|
@ -50,6 +50,8 @@ Generated by [AVA](https://avajs.dev).
|
||||||
export function concatStr(s: string): string␊
|
export function concatStr(s: string): string␊
|
||||||
export function concatUtf16(s: string): string␊
|
export function concatUtf16(s: string): string␊
|
||||||
export function concatLatin1(s: string): string␊
|
export function concatLatin1(s: string): string␊
|
||||||
|
export function setSymbolInObj(symbol: symbol): object␊
|
||||||
|
export function createSymbol(): symbol␊
|
||||||
export function withoutAbortController(a: number, b: number): Promise<number>␊
|
export function withoutAbortController(a: number, b: number): Promise<number>␊
|
||||||
export function withAbortController(a: number, b: number, signal: AbortSignal): Promise<number>␊
|
export function withAbortController(a: number, b: number, signal: AbortSignal): Promise<number>␊
|
||||||
export function callThreadsafeFunction(callback: (...args: any[]) => any): void␊
|
export function callThreadsafeFunction(callback: (...args: any[]) => any): void␊
|
||||||
|
|
Binary file not shown.
|
@ -44,6 +44,8 @@ import {
|
||||||
getGlobal,
|
getGlobal,
|
||||||
getUndefined,
|
getUndefined,
|
||||||
getNull,
|
getNull,
|
||||||
|
setSymbolInObj,
|
||||||
|
createSymbol,
|
||||||
} from '../'
|
} from '../'
|
||||||
|
|
||||||
test('number', (t) => {
|
test('number', (t) => {
|
||||||
|
@ -156,6 +158,16 @@ test('get null', (t) => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('pass symbol in', (t) => {
|
||||||
|
const sym = Symbol('test')
|
||||||
|
const obj = setSymbolInObj(sym)
|
||||||
|
t.is(obj[sym], 'a symbol')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('create symbol', (t) => {
|
||||||
|
t.is(createSymbol().toString(), 'Symbol(a symbol)')
|
||||||
|
})
|
||||||
|
|
||||||
test('Option', (t) => {
|
test('Option', (t) => {
|
||||||
t.is(mapOption(null), null)
|
t.is(mapOption(null), null)
|
||||||
t.is(mapOption(3), 4)
|
t.is(mapOption(3), 4)
|
||||||
|
|
37
examples/napi/index.d.ts
vendored
37
examples/napi/index.d.ts
vendored
|
@ -7,9 +7,7 @@ export function bigintAdd(a: BigInt, b: BigInt): BigInt
|
||||||
export function createBigInt(): BigInt
|
export function createBigInt(): BigInt
|
||||||
export function createBigIntI64(): BigInt
|
export function createBigIntI64(): BigInt
|
||||||
export function getCwd(callback: (arg0: string) => void): void
|
export function getCwd(callback: (arg0: string) => void): void
|
||||||
export function readFile(
|
export function readFile(callback: (arg0: Error | undefined, arg1: string | null) => void): void
|
||||||
callback: (arg0: Error | undefined, arg1: string | null) => void,
|
|
||||||
): void
|
|
||||||
export function eitherStringOrNumber(input: string | number): number
|
export function eitherStringOrNumber(input: string | number): number
|
||||||
export function returnEither(input: number): string | number
|
export function returnEither(input: number): string | number
|
||||||
export function either3(input: string | number | boolean): number
|
export function either3(input: string | number | boolean): number
|
||||||
|
@ -17,21 +15,8 @@ interface Obj {
|
||||||
v: string | number
|
v: string | number
|
||||||
}
|
}
|
||||||
export function either4(input: string | number | boolean | Obj): number
|
export function either4(input: string | number | boolean | Obj): number
|
||||||
export enum Kind {
|
export enum Kind { Dog = 0, Cat = 1, Duck = 2 }
|
||||||
Dog = 0,
|
export enum CustomNumEnum { One = 1, Two = 2, Three = 3, Four = 4, Six = 6, Eight = 8, Nine = 9, Ten = 10 }
|
||||||
Cat = 1,
|
|
||||||
Duck = 2,
|
|
||||||
}
|
|
||||||
export enum CustomNumEnum {
|
|
||||||
One = 1,
|
|
||||||
Two = 2,
|
|
||||||
Three = 3,
|
|
||||||
Four = 4,
|
|
||||||
Six = 6,
|
|
||||||
Eight = 8,
|
|
||||||
Nine = 9,
|
|
||||||
Ten = 10,
|
|
||||||
}
|
|
||||||
export function enumToI32(e: CustomNumEnum): number
|
export function enumToI32(e: CustomNumEnum): number
|
||||||
export function throwError(): void
|
export function throwError(): void
|
||||||
export function mapOption(val: number | null): number | null
|
export function mapOption(val: number | null): number | null
|
||||||
|
@ -40,7 +25,7 @@ export function fibonacci(n: number): number
|
||||||
export function listObjKeys(obj: object): Array<string>
|
export function listObjKeys(obj: object): Array<string>
|
||||||
export function createObj(): object
|
export function createObj(): object
|
||||||
export function getGlobal(): typeof global
|
export function getGlobal(): typeof global
|
||||||
export function getUndefined(): JsUndefined
|
export function getUndefined(): void
|
||||||
export function getNull(): JsNull
|
export function getNull(): JsNull
|
||||||
export function asyncPlus100(p: Promise<number>): Promise<number>
|
export function asyncPlus100(p: Promise<number>): Promise<number>
|
||||||
interface PackageJson {
|
interface PackageJson {
|
||||||
|
@ -55,12 +40,10 @@ export function contains(source: string, target: string): boolean
|
||||||
export function concatStr(s: string): string
|
export function concatStr(s: string): string
|
||||||
export function concatUtf16(s: string): string
|
export function concatUtf16(s: string): string
|
||||||
export function concatLatin1(s: string): string
|
export function concatLatin1(s: string): string
|
||||||
|
export function setSymbolInObj(symbol: symbol): object
|
||||||
|
export function createSymbol(): symbol
|
||||||
export function withoutAbortController(a: number, b: number): Promise<number>
|
export function withoutAbortController(a: number, b: number): Promise<number>
|
||||||
export function withAbortController(
|
export function withAbortController(a: number, b: number, signal: AbortSignal): Promise<number>
|
||||||
a: number,
|
|
||||||
b: number,
|
|
||||||
signal: AbortSignal,
|
|
||||||
): Promise<number>
|
|
||||||
export function callThreadsafeFunction(callback: (...args: any[]) => any): void
|
export function callThreadsafeFunction(callback: (...args: any[]) => any): void
|
||||||
export function threadsafeFunctionThrowError(cb: (...args: any[]) => any): void
|
export function threadsafeFunctionThrowError(cb: (...args: any[]) => any): void
|
||||||
export function getBuffer(): Buffer
|
export function getBuffer(): Buffer
|
||||||
|
@ -74,10 +57,14 @@ export class Animal {
|
||||||
static getDogKind(): Kind
|
static getDogKind(): Kind
|
||||||
}
|
}
|
||||||
export class Blake2BHasher {
|
export class Blake2BHasher {
|
||||||
|
|
||||||
static withKey(key: Blake2bKey): Blake2BHasher
|
static withKey(key: Blake2bKey): Blake2BHasher
|
||||||
}
|
}
|
||||||
export class Blake2BKey {}
|
export class Blake2BKey {
|
||||||
|
|
||||||
|
}
|
||||||
export class Context {
|
export class Context {
|
||||||
|
|
||||||
constructor()
|
constructor()
|
||||||
static withData(data: string): Context
|
static withData(data: string): Context
|
||||||
method(): string
|
method(): string
|
||||||
|
|
|
@ -18,6 +18,7 @@ mod object;
|
||||||
mod promise;
|
mod promise;
|
||||||
mod serde;
|
mod serde;
|
||||||
mod string;
|
mod string;
|
||||||
|
mod symbol;
|
||||||
mod task;
|
mod task;
|
||||||
mod threadsafe_function;
|
mod threadsafe_function;
|
||||||
mod typed_array;
|
mod typed_array;
|
||||||
|
|
13
examples/napi/src/symbol.rs
Normal file
13
examples/napi/src/symbol.rs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
use napi::{bindgen_prelude::*, Env, JsObject, JsSymbol};
|
||||||
|
|
||||||
|
#[napi]
|
||||||
|
pub fn set_symbol_in_obj(env: Env, symbol: JsSymbol) -> Result<JsObject> {
|
||||||
|
let mut obj = env.create_object()?;
|
||||||
|
obj.set_property(symbol, env.create_string("a symbol")?)?;
|
||||||
|
Ok(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[napi]
|
||||||
|
pub fn create_symbol() -> Symbol {
|
||||||
|
Symbol::new("a symbol".to_owned())
|
||||||
|
}
|
Loading…
Reference in a new issue