From d7dc4dc5a26bc2d5d0b2a7be531175bb9246d3d2 Mon Sep 17 00:00:00 2001 From: LongYinan Date: Thu, 15 Feb 2024 15:43:21 +0800 Subject: [PATCH] feat(napi): extends the Map types interoperability (#1950) --- crates/napi/Cargo.toml | 6 + .../napi/src/bindgen_runtime/js_values/map.rs | 103 +++++++++++++++++- examples/napi/Cargo.toml | 3 + .../__snapshots__/typegen.spec.ts.md | 10 ++ .../__snapshots__/typegen.spec.ts.snap | Bin 4294 -> 4352 bytes examples/napi/__tests__/values.spec.ts | 10 ++ examples/napi/index.d.ts | 10 ++ examples/napi/src/map.rs | 35 +++++- 8 files changed, 175 insertions(+), 2 deletions(-) diff --git a/crates/napi/Cargo.toml b/crates/napi/Cargo.toml index d1990c7f..22f864db 100644 --- a/crates/napi/Cargo.toml +++ b/crates/napi/Cargo.toml @@ -28,6 +28,7 @@ deferred_trace = ["napi4"] error_anyhow = ["anyhow"] experimental = ["napi-sys/experimental"] full = ["latin1", "napi9", "async", "serde-json", "experimental", "chrono_date"] +object_indexmap = ["indexmap"] latin1 = ["encoding_rs"] napi1 = [] napi2 = ["napi1", "napi-sys/napi2"] @@ -40,6 +41,7 @@ napi8 = ["napi7", "napi-sys/napi8"] napi9 = ["napi8", "napi-sys/napi9"] noop = [] serde-json = ["serde", "serde_json"] +serde-json-ordered = ["serde-json", "serde_json/preserve_order"] tokio_fs = ["tokio/fs"] tokio_full = ["tokio/full"] tokio_io_std = ["tokio/io-std"] @@ -93,3 +95,7 @@ version = "1" [dependencies.serde_json] optional = true version = "1" + +[dependencies.indexmap] +optional = true +version = "2" diff --git a/crates/napi/src/bindgen_runtime/js_values/map.rs b/crates/napi/src/bindgen_runtime/js_values/map.rs index 1a7e8c28..4534da0e 100644 --- a/crates/napi/src/bindgen_runtime/js_values/map.rs +++ b/crates/napi/src/bindgen_runtime/js_values/map.rs @@ -1,6 +1,9 @@ -use std::collections::HashMap; +use std::collections::{BTreeMap, HashMap}; use std::hash::{BuildHasher, Hash}; +#[cfg(feature = "object_indexmap")] +use indexmap::IndexMap; + use crate::bindgen_prelude::{Env, Result, ToNapiValue, *}; impl TypeName for HashMap { @@ -49,3 +52,101 @@ where Ok(map) } } + +impl TypeName for BTreeMap { + fn type_name() -> &'static str { + "BTreeMap" + } + + fn value_type() -> ValueType { + ValueType::Object + } +} + +impl + Ord, V: FromNapiValue> ValidateNapiValue for BTreeMap {} + +impl ToNapiValue for BTreeMap +where + K: AsRef, + V: ToNapiValue, +{ + unsafe fn to_napi_value(raw_env: sys::napi_env, val: Self) -> Result { + let env = Env::from(raw_env); + let mut obj = env.create_object()?; + for (k, v) in val.into_iter() { + obj.set(k.as_ref(), v)?; + } + + unsafe { Object::to_napi_value(raw_env, obj) } + } +} + +impl FromNapiValue for BTreeMap +where + K: From + Ord, + V: FromNapiValue, +{ + unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> Result { + let obj = unsafe { Object::from_napi_value(env, napi_val)? }; + let mut map = BTreeMap::default(); + for key in Object::keys(&obj)?.into_iter() { + if let Some(val) = obj.get(&key)? { + map.insert(K::from(key), val); + } + } + + Ok(map) + } +} + +#[cfg(feature = "object_indexmap")] +impl TypeName for IndexMap { + fn type_name() -> &'static str { + "IndexMap" + } + + fn value_type() -> ValueType { + ValueType::Object + } +} + +#[cfg(feature = "object_indexmap")] +impl + Hash + Eq, V: FromNapiValue> ValidateNapiValue for IndexMap {} + +#[cfg(feature = "object_indexmap")] +impl ToNapiValue for IndexMap +where + K: AsRef, + V: ToNapiValue, + S: Default + BuildHasher, +{ + unsafe fn to_napi_value(raw_env: sys::napi_env, val: Self) -> Result { + let env = Env::from(raw_env); + let mut obj = env.create_object()?; + for (k, v) in val.into_iter() { + obj.set(k.as_ref(), v)?; + } + + unsafe { Object::to_napi_value(raw_env, obj) } + } +} + +#[cfg(feature = "object_indexmap")] +impl FromNapiValue for IndexMap +where + K: From + Hash + Eq, + V: FromNapiValue, + S: Default + BuildHasher, +{ + unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> Result { + let obj = unsafe { Object::from_napi_value(env, napi_val)? }; + let mut map = IndexMap::default(); + for key in Object::keys(&obj)?.into_iter() { + if let Some(val) = obj.get(&key)? { + map.insert(K::from(key), val); + } + } + + Ok(map) + } +} diff --git a/examples/napi/Cargo.toml b/examples/napi/Cargo.toml index 311e49a5..2a359cf4 100644 --- a/examples/napi/Cargo.toml +++ b/examples/napi/Cargo.toml @@ -19,6 +19,7 @@ napi-shared = { path = "../napi-shared" } serde = "1" serde_derive = "1" serde_json = "1" +indexmap = "2" [target.'cfg(not(target_family = "wasm"))'.dependencies] napi = { path = "../../crates/napi", default-features = false, features = [ @@ -27,6 +28,7 @@ napi = { path = "../../crates/napi", default-features = false, features = [ "experimental", "latin1", "chrono_date", + "object_indexmap", "tokio", "async", "tokio_rt", @@ -43,6 +45,7 @@ napi = { path = "../../crates/napi", default-features = false, features = [ "experimental", "latin1", "chrono_date", + "object_indexmap", "tokio", "async", "tokio_rt", diff --git a/examples/napi/__tests__/__snapshots__/typegen.spec.ts.md b/examples/napi/__tests__/__snapshots__/typegen.spec.ts.md index 3b6b9133..9c63b059 100644 --- a/examples/napi/__tests__/__snapshots__/typegen.spec.ts.md +++ b/examples/napi/__tests__/__snapshots__/typegen.spec.ts.md @@ -392,6 +392,8 @@ Generated by [AVA](https://avajs.dev). ␊ export function fnReceivedAliased(s: AliasedStruct, e: ALIAS): void␊ ␊ + export function getBtreeMapping(): BTreeMap␊ + ␊ export function getBuffer(): Buffer␊ ␊ export function getCwd(callback: (arg0: string) => void): void␊ @@ -402,6 +404,8 @@ Generated by [AVA](https://avajs.dev). ␊ export function getGlobal(): typeof global␊ ␊ + export function getIndexMapping(): IndexMap␊ + ␊ export function getMapping(): Record␊ ␊ export function getModuleFileName(): string␊ @@ -425,6 +429,8 @@ Generated by [AVA](https://avajs.dev). ␊ export function getWords(): Array␊ ␊ + export function indexmapPassthrough(fixture: IndexMap): IndexMap␊ + ␊ /** default enum values are continuos i32s start from 0 */␊ export const enum Kind {␊ /** Barks */␊ @@ -544,6 +550,10 @@ Generated by [AVA](https://avajs.dev). name: string␊ }␊ ␊ + export function sumBtreeMapping(nums: BTreeMap): number␊ + ␊ + export function sumIndexMapping(nums: IndexMap): number␊ + ␊ export function sumMapping(nums: Record): number␊ ␊ export function sumNums(nums: Array): number␊ diff --git a/examples/napi/__tests__/__snapshots__/typegen.spec.ts.snap b/examples/napi/__tests__/__snapshots__/typegen.spec.ts.snap index 8c15e912cd569664e708c472084f644959354e8b..f74ab62bee9a3cfb0fedb961feef0b9dc9637953 100644 GIT binary patch literal 4352 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 diff --git a/examples/napi/__tests__/values.spec.ts b/examples/napi/__tests__/values.spec.ts index 4de2771b..7807e55c 100644 --- a/examples/napi/__tests__/values.spec.ts +++ b/examples/napi/__tests__/values.spec.ts @@ -34,6 +34,11 @@ const { sumNums, getMapping, sumMapping, + getBtreeMapping, + sumBtreeMapping, + getIndexMapping, + sumIndexMapping, + indexmapPassthrough, getCwd, Animal, Kind, @@ -202,6 +207,11 @@ test('array', (t) => { test('map', (t) => { t.deepEqual(getMapping(), { a: 101, b: 102 }) t.is(sumMapping({ a: 101, b: 102 }), 203) + t.deepEqual(getBtreeMapping(), { a: 101, b: 102 }) + t.is(sumBtreeMapping({ a: 101, b: 102 }), 203) + t.deepEqual(getIndexMapping(), { a: 101, b: 102 }) + t.is(sumIndexMapping({ a: 101, b: 102 }), 203) + t.deepEqual(indexmapPassthrough({ a: 101, b: 102 }), { a: 101, b: 102 }) }) test('enum', (t) => { diff --git a/examples/napi/index.d.ts b/examples/napi/index.d.ts index 72b926a1..8dd4e2f9 100644 --- a/examples/napi/index.d.ts +++ b/examples/napi/index.d.ts @@ -382,6 +382,8 @@ export function fibonacci(n: number): number export function fnReceivedAliased(s: AliasedStruct, e: ALIAS): void +export function getBtreeMapping(): BTreeMap + export function getBuffer(): Buffer export function getCwd(callback: (arg0: string) => void): void @@ -392,6 +394,8 @@ export function getExternal(external: ExternalObject): number export function getGlobal(): typeof global +export function getIndexMapping(): IndexMap + export function getMapping(): Record export function getModuleFileName(): string @@ -415,6 +419,8 @@ export function getUndefined(): void export function getWords(): Array +export function indexmapPassthrough(fixture: IndexMap): IndexMap + /** default enum values are continuos i32s start from 0 */ export const enum Kind { /** Barks */ @@ -534,6 +540,10 @@ export interface StrictObject { name: string } +export function sumBtreeMapping(nums: BTreeMap): number + +export function sumIndexMapping(nums: IndexMap): number + export function sumMapping(nums: Record): number export function sumNums(nums: Array): number diff --git a/examples/napi/src/map.rs b/examples/napi/src/map.rs index c4d0bd43..d2f659be 100644 --- a/examples/napi/src/map.rs +++ b/examples/napi/src/map.rs @@ -1,4 +1,6 @@ -use std::collections::HashMap; +use std::collections::{BTreeMap, HashMap}; + +use indexmap::IndexMap; #[napi] fn get_mapping() -> HashMap { @@ -12,3 +14,34 @@ fn get_mapping() -> HashMap { fn sum_mapping(nums: HashMap) -> u32 { nums.into_values().sum() } + +#[napi] +fn get_btree_mapping() -> BTreeMap { + let mut map = BTreeMap::new(); + map.insert("a".to_string(), 101); + map.insert("b".to_string(), 102); + map +} + +#[napi] +fn sum_btree_mapping(nums: BTreeMap) -> u32 { + nums.into_values().sum() +} + +#[napi] +fn get_index_mapping() -> IndexMap { + let mut map = IndexMap::new(); + map.insert("a".to_string(), 101); + map.insert("b".to_string(), 102); + map +} + +#[napi] +fn sum_index_mapping(nums: IndexMap) -> u32 { + nums.into_values().sum() +} + +#[napi] +fn indexmap_passthrough(fixture: IndexMap) -> IndexMap { + fixture +}