Merge pull request #35 from Brooooooklyn/try-from

refactor(napi-rs): impl TryFrom instead of TryInto
This commit is contained in:
LongYinan 2020-04-26 19:14:54 +08:00 committed by GitHub
commit 4f215b04fa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 77 additions and 44 deletions

View file

@ -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_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_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_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_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_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_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_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 | ⛔️ | | [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_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_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_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_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_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_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_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_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_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 | ✅ | |[napi_get_null](https://nodejs.org/api/n-api.html#n_api_napi_get_null)| 1 | v8.0.0 | ✅ |

View file

@ -3,7 +3,7 @@ extern crate napi_rs as napi;
#[macro_use] #[macro_use]
extern crate napi_derive; 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; use std::convert::TryInto;
register_module!(test_module, init); register_module!(test_module, init);
@ -12,22 +12,14 @@ fn init<'env>(
env: &'env Env, env: &'env Env,
exports: &'env mut Value<'env, Object>, exports: &'env mut Value<'env, Object>,
) -> Result<Option<Value<'env, Object>>> { ) -> Result<Option<Value<'env, Object>>> {
exports.set_named_property( exports.set_named_property("testThrow", env.create_function("testThrow", test_throw)?)?;
"testThrow",
env.create_function("testThrow", test_throw)?,
)?;
exports.set_named_property( exports.set_named_property("fibonacci", env.create_function("fibonacci", fibonacci)?)?;
"fibonacci",
env.create_function("fibonacci", fibonacci)?,
)?;
Ok(None) Ok(None)
} }
#[js_function] #[js_function]
fn test_throw<'a>( fn test_throw<'a>(_ctx: CallContext) -> Result<Value<'a, Any>> {
_ctx: CallContext,
) -> Result<Value<'a, Any>> {
Err(Error::new(Status::GenericFailure)) Err(Error::new(Status::GenericFailure))
} }
@ -41,6 +33,6 @@ fn fibonacci<'env>(ctx: CallContext<'env>) -> Result<Value<'env, Number>> {
fn fibonacci_native(n: i64) -> i64 { fn fibonacci_native(n: i64) -> i64 {
match n { match n {
1 | 2 => 1, 1 | 2 => 1,
_ => fibonacci_native(n - 1) + fibonacci_native(n - 2) _ => fibonacci_native(n - 1) + fibonacci_native(n - 2),
} }
} }

View file

@ -2,11 +2,11 @@ extern crate proc_macro;
use proc_macro::TokenStream; use proc_macro::TokenStream;
use proc_macro2::{Ident, Literal}; use proc_macro2::{Ident, Literal};
use quote::{quote, format_ident}; use quote::{format_ident, quote};
use syn::fold::{fold_signature, fold_fn_arg, Fold}; use syn::fold::{fold_fn_arg, fold_signature, Fold};
use syn::parse::{Parse, ParseStream, Result}; use syn::parse::{Parse, ParseStream, Result};
use syn::punctuated::Punctuated; 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 { struct ArgLength {
length: Option<Literal>, length: Option<Literal>,
@ -14,10 +14,10 @@ struct ArgLength {
impl Parse for ArgLength { impl Parse for ArgLength {
fn parse(input: ParseStream) -> Result<Self> { fn parse(input: ParseStream) -> Result<Self> {
let vars = Punctuated::<Literal, Token![,]>::parse_terminated(input)?; let vars = Punctuated::<Literal, Token![,]>::parse_terminated(input)?;
Ok(ArgLength { Ok(ArgLength {
length: vars.first().map(|i| i.clone()), length: vars.first().map(|i| i.clone()),
}) })
} }
} }

View file

@ -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 struct CallContext<'env, T: ValueType = Any> {
pub env: &'env Env, pub env: &'env Env,
@ -7,9 +7,19 @@ pub struct CallContext<'env, T: ValueType = Any> {
arg_len: usize, arg_len: usize,
} }
impl <'env, T: ValueType> CallContext <'env, T> { 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<Self> { pub fn new(
Ok(Self { env, this: Value::<'env, T>::from_raw(env, this)?, args, arg_len }) env: &'env Env,
this: sys::napi_value,
args: [sys::napi_value; 8],
arg_len: usize,
) -> Result<Self> {
Ok(Self {
env,
this: Value::<'env, T>::from_raw(env, this)?,
args,
arg_len,
})
} }
pub fn get<ArgType: ValueType>(&'env self, index: usize) -> Result<Value<'env, ArgType>> { pub fn get<ArgType: ValueType>(&'env self, index: usize) -> Result<Value<'env, ArgType>> {

View file

@ -1,7 +1,7 @@
extern crate futures; extern crate futures;
use std::any::TypeId; use std::any::TypeId;
use std::convert::TryInto; use std::convert::{TryFrom, TryInto};
use std::ffi::CString; use std::ffi::CString;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::mem; use std::mem;
@ -11,9 +11,9 @@ use std::ptr;
use std::slice; use std::slice;
use std::string::String as RustString; use std::string::String as RustString;
mod call_context;
mod executor; mod executor;
pub mod sys; pub mod sys;
mod call_context;
pub use call_context::CallContext; pub use call_context::CallContext;
pub use sys::{napi_valuetype, Status}; pub use sys::{napi_valuetype, Status};
@ -47,6 +47,7 @@ pub struct Boolean {
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub enum Number { pub enum Number {
Int(i64), Int(i64),
Int32(i32),
U32(u32), U32(u32),
Double(f64), Double(f64),
} }
@ -199,6 +200,14 @@ impl Env {
Ok(Value::from_raw_value(self, raw_value, Boolean { value })) Ok(Value::from_raw_value(self, raw_value, Boolean { value }))
} }
pub fn create_int32<'a>(&'a self, int: i32) -> Result<Value<'a, Number>> {
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<Value<'a, Number>> { pub fn create_int64<'a>(&'a self, int: i64) -> Result<Value<'a, Number>> {
let mut raw_value = ptr::null_mut(); let mut raw_value = ptr::null_mut();
let status = let status =
@ -829,17 +838,17 @@ impl<'env> Value<'env, String> {
} }
} }
impl<'env> TryInto<Vec<u16>> for Value<'env, String> { impl<'env> TryFrom<Value<'env, String>> for Vec<u16> {
type Error = Error; type Error = Error;
fn try_into(self) -> Result<Vec<u16>> { fn try_from(value: Value<'env, String>) -> Result<Vec<u16>> {
let mut result = Vec::with_capacity(self.len()? + 1); // Leave room for trailing null byte let mut result = Vec::with_capacity(value.len()? + 1); // Leave room for trailing null byte
unsafe { unsafe {
let mut written_char_count = 0; let mut written_char_count = 0;
let status = sys::napi_get_value_string_utf16( let status = sys::napi_get_value_string_utf16(
self.env.0, value.env.0,
self.raw_value, value.raw_value,
result.as_mut_ptr(), result.as_mut_ptr(),
result.capacity() as u64, result.capacity() as u64,
&mut written_char_count, &mut written_char_count,
@ -852,34 +861,56 @@ impl<'env> TryInto<Vec<u16>> for Value<'env, String> {
} }
} }
impl<'env> TryInto<usize> for Value<'env, Number> { impl<'env> TryFrom<Value<'env, Number>> for usize {
type Error = Error; type Error = Error;
fn try_into(self) -> Result<usize> { fn try_from(value: Value<'env, Number>) -> Result<usize> {
let mut result = 0; 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)?; check_status(status)?;
Ok(result as usize) Ok(result as usize)
} }
} }
impl<'env> TryInto<i64> for Value<'env, Number> { impl<'env> TryFrom<Value<'env, Number>> for u32 {
type Error = Error; type Error = Error;
fn try_into(self) -> Result<i64> { fn try_from(value: Value<'env, Number>) -> Result<u32> {
let mut result = 0; 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)?; check_status(status)?;
Ok(result) Ok(result)
} }
} }
impl<'env> TryInto<f64> for Value<'env, Number> { impl<'env> TryFrom<Value<'env, Number>> for i32 {
type Error = Error; type Error = Error;
fn try_into(self) -> Result<f64> { fn try_from(value: Value<'env, Number>) -> Result<i32> {
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<Value<'env, Number>> for i64 {
type Error = Error;
fn try_from(value: Value<'env, Number>) -> Result<i64> {
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<Value<'env, Number>> for f64 {
type Error = Error;
fn try_from(value: Value<'env, Number>) -> Result<f64> {
let mut result = 0_f64; 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)?; check_status(status)?;
Ok(result) Ok(result)
} }