From 4c0341961ca932657bc834a80ce589dddce77f43 Mon Sep 17 00:00:00 2001 From: LongYinan Date: Sun, 26 Apr 2020 18:46:56 +0800 Subject: [PATCH] refactor(napi-rs): impl TryFrom instead of TryInto --- README.md | 8 ++--- napi-derive-example/src/lib.rs | 18 +++------- napi-derive/src/lib.rs | 14 ++++---- napi/src/call_context.rs | 18 +++++++--- napi/src/lib.rs | 63 +++++++++++++++++++++++++--------- 5 files changed, 77 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index 32e11029..4be6e387 100644 --- a/README.md +++ b/README.md @@ -126,10 +126,10 @@ npm test | [napi_create_symbol](https://nodejs.org/api/n-api.html#n_api_napi_create_symbol) | 1 | v8.0.0 | ⛔️ | | [napi_create_typedarray](https://nodejs.org/api/n-api.html#n_api_napi_create_typedarray) | 1 | v8.0.0 | ⛔️ | | [napi_create_dataview](https://nodejs.org/api/n-api.html#n_api_napi_create_dataview) | 1 | v8.3.0 | ⛔️ | -| [napi_create_int32](https://nodejs.org/api/n-api.html#n_api_napi_create_int32) | 1 | v8.4.0 | ⛔️ | +| [napi_create_int32](https://nodejs.org/api/n-api.html#n_api_napi_create_int32) | 1 | v8.4.0 | ✅ | | [napi_create_uint32](https://nodejs.org/api/n-api.html#n_api_napi_create_uint32) | 1 | v8.4.0 | ✅ | | [napi_create_int64](https://nodejs.org/api/n-api.html#n_api_napi_create_int64) | 1 | v8.4.0 | ✅ | -| [napi_create_double](https://nodejs.org/api/n-api.html#n_api_napi_create_double) | 1 | v8.4.0 | ⛔️ | +| [napi_create_double](https://nodejs.org/api/n-api.html#n_api_napi_create_double) | 1 | v8.4.0 | ✅ | | [napi_create_bigint_int64](https://nodejs.org/api/n-api.html#n_api_napi_create_bigint_int64) | 6 | v10.7.0 | ⛔️ | | [napi_create_bigint_uint64](https://nodejs.org/api/n-api.html#n_api_napi_create_bigint_uint64) | 6 | v10.7.0 | ⛔️ | | [napi_create_bigint_words](https://nodejs.org/api/n-api.html#n_api_napi_create_bigint_words) | 6 | v10.7.0 | ⛔️ | @@ -154,12 +154,12 @@ npm test |[napi_get_value_bigint_uint64](https://nodejs.org/api/n-api.html#n_api_napi_get_value_bigint_uint64)| 6 | v10.7.0 | ⛔️ | |[napi_get_value_bigint_words](https://nodejs.org/api/n-api.html#n_api_napi_get_value_bigint_words)| 6 | v10.7.0 | ⛔️ | |[napi_get_value_external](https://nodejs.org/api/n-api.html#n_api_napi_get_value_external)| 1 | v8.0.0 | ⛔️ | -|[napi_get_value_int32](https://nodejs.org/api/n-api.html#n_api_napi_get_value_int32)| 1 | v8.0.0 | ⛔️ | +|[napi_get_value_int32](https://nodejs.org/api/n-api.html#n_api_napi_get_value_int32)| 1 | v8.0.0 | ✅ | |[napi_get_value_int64](https://nodejs.org/api/n-api.html#n_api_napi_get_value_int64)| 1 | v8.0.0 | ✅ | |[napi_get_value_string_latin1](https://nodejs.org/api/n-api.html#n_api_napi_get_value_string_latin1)| 1 | v8.0.0 | ⛔️ | |[napi_get_value_string_utf8](https://nodejs.org/api/n-api.html#n_api_napi_get_value_string_utf8)| 1 | v8.0.0 | ✅ | |[napi_get_value_string_utf16](https://nodejs.org/api/n-api.html#n_api_napi_get_value_string_utf16)| 1 | v8.0.0 | ✅ | -|[napi_get_value_uint32](https://nodejs.org/api/n-api.html#n_api_napi_get_value_uint32)| 1 | v8.0.0 | ⛔️ | +|[napi_get_value_uint32](https://nodejs.org/api/n-api.html#n_api_napi_get_value_uint32)| 1 | v8.0.0 | ✅ | |[napi_get_boolean](https://nodejs.org/api/n-api.html#n_api_napi_get_boolean)| 1 | v8.0.0 | ✅ | |[napi_get_global](https://nodejs.org/api/n-api.html#n_api_napi_get_global)| 1 | v8.0.0 | ⛔️ | |[napi_get_null](https://nodejs.org/api/n-api.html#n_api_napi_get_null)| 1 | v8.0.0 | ✅ | diff --git a/napi-derive-example/src/lib.rs b/napi-derive-example/src/lib.rs index c1696b0d..dee4b20c 100644 --- a/napi-derive-example/src/lib.rs +++ b/napi-derive-example/src/lib.rs @@ -3,7 +3,7 @@ extern crate napi_rs as napi; #[macro_use] extern crate napi_derive; -use napi::{Any, Env, Error, Object, Result, Status, Value, CallContext, Number}; +use napi::{Any, CallContext, Env, Error, Number, Object, Result, Status, Value}; use std::convert::TryInto; register_module!(test_module, init); @@ -12,22 +12,14 @@ fn init<'env>( env: &'env Env, exports: &'env mut Value<'env, Object>, ) -> Result>> { - exports.set_named_property( - "testThrow", - env.create_function("testThrow", test_throw)?, - )?; + exports.set_named_property("testThrow", env.create_function("testThrow", test_throw)?)?; - exports.set_named_property( - "fibonacci", - env.create_function("fibonacci", fibonacci)?, - )?; + exports.set_named_property("fibonacci", env.create_function("fibonacci", fibonacci)?)?; Ok(None) } #[js_function] -fn test_throw<'a>( - _ctx: CallContext, -) -> Result> { +fn test_throw<'a>(_ctx: CallContext) -> Result> { Err(Error::new(Status::GenericFailure)) } @@ -41,6 +33,6 @@ fn fibonacci<'env>(ctx: CallContext<'env>) -> Result> { fn fibonacci_native(n: i64) -> i64 { match n { 1 | 2 => 1, - _ => fibonacci_native(n - 1) + fibonacci_native(n - 2) + _ => fibonacci_native(n - 1) + fibonacci_native(n - 2), } } diff --git a/napi-derive/src/lib.rs b/napi-derive/src/lib.rs index 329555c1..e63b2226 100644 --- a/napi-derive/src/lib.rs +++ b/napi-derive/src/lib.rs @@ -2,11 +2,11 @@ extern crate proc_macro; use proc_macro::TokenStream; use proc_macro2::{Ident, Literal}; -use quote::{quote, format_ident}; -use syn::fold::{fold_signature, fold_fn_arg, Fold}; +use quote::{format_ident, quote}; +use syn::fold::{fold_fn_arg, fold_signature, Fold}; use syn::parse::{Parse, ParseStream, Result}; use syn::punctuated::Punctuated; -use syn::{parse_macro_input, FnArg, ItemFn, Signature, Block, Token}; +use syn::{parse_macro_input, Block, FnArg, ItemFn, Signature, Token}; struct ArgLength { length: Option, @@ -14,10 +14,10 @@ struct ArgLength { impl Parse for ArgLength { fn parse(input: ParseStream) -> Result { - let vars = Punctuated::::parse_terminated(input)?; - Ok(ArgLength { - length: vars.first().map(|i| i.clone()), - }) + let vars = Punctuated::::parse_terminated(input)?; + Ok(ArgLength { + length: vars.first().map(|i| i.clone()), + }) } } diff --git a/napi/src/call_context.rs b/napi/src/call_context.rs index 40aa417b..4b826ea1 100644 --- a/napi/src/call_context.rs +++ b/napi/src/call_context.rs @@ -1,4 +1,4 @@ -use crate::{Any, Value, Env, ValueType, Error, Status, Result, sys}; +use crate::{sys, Any, Env, Error, Result, Status, Value, ValueType}; pub struct CallContext<'env, T: ValueType = Any> { pub env: &'env Env, @@ -7,9 +7,19 @@ pub struct CallContext<'env, T: ValueType = Any> { arg_len: usize, } -impl <'env, T: ValueType> CallContext <'env, T> { - pub fn new(env: &'env Env, this: sys::napi_value, args: [sys::napi_value; 8], arg_len: usize) -> Result { - Ok(Self { env, this: Value::<'env, T>::from_raw(env, this)?, args, arg_len }) +impl<'env, T: ValueType> CallContext<'env, T> { + pub fn new( + env: &'env Env, + this: sys::napi_value, + args: [sys::napi_value; 8], + arg_len: usize, + ) -> Result { + Ok(Self { + env, + this: Value::<'env, T>::from_raw(env, this)?, + args, + arg_len, + }) } pub fn get(&'env self, index: usize) -> Result> { diff --git a/napi/src/lib.rs b/napi/src/lib.rs index 8768c72e..e0c1f857 100644 --- a/napi/src/lib.rs +++ b/napi/src/lib.rs @@ -1,7 +1,7 @@ extern crate futures; use std::any::TypeId; -use std::convert::TryInto; +use std::convert::{TryFrom, TryInto}; use std::ffi::CString; use std::marker::PhantomData; use std::mem; @@ -11,9 +11,9 @@ use std::ptr; use std::slice; use std::string::String as RustString; +mod call_context; mod executor; pub mod sys; -mod call_context; pub use call_context::CallContext; pub use sys::{napi_valuetype, Status}; @@ -47,6 +47,7 @@ pub struct Boolean { #[derive(Clone, Copy, Debug)] pub enum Number { Int(i64), + Int32(i32), U32(u32), Double(f64), } @@ -199,6 +200,14 @@ impl Env { Ok(Value::from_raw_value(self, raw_value, Boolean { value })) } + pub fn create_int32<'a>(&'a self, int: i32) -> Result> { + let mut raw_value = ptr::null_mut(); + let status = + unsafe { sys::napi_create_int32(self.0, int, (&mut raw_value) as *mut sys::napi_value) }; + check_status(status)?; + Ok(Value::from_raw_value(self, raw_value, Number::Int32(int))) + } + pub fn create_int64<'a>(&'a self, int: i64) -> Result> { let mut raw_value = ptr::null_mut(); let status = @@ -829,17 +838,17 @@ impl<'env> Value<'env, String> { } } -impl<'env> TryInto> for Value<'env, String> { +impl<'env> TryFrom> for Vec { type Error = Error; - fn try_into(self) -> Result> { - let mut result = Vec::with_capacity(self.len()? + 1); // Leave room for trailing null byte + fn try_from(value: Value<'env, String>) -> Result> { + let mut result = Vec::with_capacity(value.len()? + 1); // Leave room for trailing null byte unsafe { let mut written_char_count = 0; let status = sys::napi_get_value_string_utf16( - self.env.0, - self.raw_value, + value.env.0, + value.raw_value, result.as_mut_ptr(), result.capacity() as u64, &mut written_char_count, @@ -852,34 +861,56 @@ impl<'env> TryInto> for Value<'env, String> { } } -impl<'env> TryInto for Value<'env, Number> { +impl<'env> TryFrom> for usize { type Error = Error; - fn try_into(self) -> Result { + fn try_from(value: Value<'env, Number>) -> Result { let mut result = 0; - let status = unsafe { sys::napi_get_value_int64(self.env.0, self.raw_value, &mut result) }; + let status = unsafe { sys::napi_get_value_int64(value.env.0, value.raw_value, &mut result) }; check_status(status)?; Ok(result as usize) } } -impl<'env> TryInto for Value<'env, Number> { +impl<'env> TryFrom> for u32 { type Error = Error; - fn try_into(self) -> Result { + fn try_from(value: Value<'env, Number>) -> Result { let mut result = 0; - let status = unsafe { sys::napi_get_value_int64(self.env.0, self.raw_value, &mut result) }; + let status = unsafe { sys::napi_get_value_uint32(value.env.0, value.raw_value, &mut result) }; check_status(status)?; Ok(result) } } -impl<'env> TryInto for Value<'env, Number> { +impl<'env> TryFrom> for i32 { type Error = Error; - fn try_into(self) -> Result { + fn try_from(value: Value<'env, Number>) -> Result { + let mut result = 0; + let status = unsafe { sys::napi_get_value_int32(value.env.0, value.raw_value, &mut result) }; + check_status(status)?; + Ok(result) + } +} + +impl<'env> TryFrom> for i64 { + type Error = Error; + + fn try_from(value: Value<'env, Number>) -> Result { + let mut result = 0; + let status = unsafe { sys::napi_get_value_int64(value.env.0, value.raw_value, &mut result) }; + check_status(status)?; + Ok(result) + } +} + +impl<'env> TryFrom> for f64 { + type Error = Error; + + fn try_from(value: Value<'env, Number>) -> Result { let mut result = 0_f64; - let status = unsafe { sys::napi_get_value_double(self.env.0, self.raw_value, &mut result) }; + let status = unsafe { sys::napi_get_value_double(value.env.0, value.raw_value, &mut result) }; check_status(status)?; Ok(result) }