From a7c4fc8fb27bcbe5e2d30f54a733f065b67b98b1 Mon Sep 17 00:00:00 2001 From: zhangyuang Date: Tue, 19 Nov 2024 21:37:27 +0800 Subject: [PATCH] chore: code optimize --- Cargo.toml | 2 + src/datatype/function.rs | 2 +- src/datatype/pointer.rs | 13 ++--- src/datatype/restore_struct.rs | 2 +- src/define.rs | 104 +++++++++++---------------------- src/lib.rs | 2 +- src/utils/dataprocess.rs | 10 ++-- src/utils/object_utils.rs | 4 +- 8 files changed, 51 insertions(+), 88 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ffdb2bd..285bb25 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,8 @@ libffi-sys = { version = "^2.3.0" } libc = "0.2" indexmap = "2.0" widestring = "1.1.0" +strum = "0.26" +strum_macros = "0.26" [build-dependencies] napi-build = "2.0.1" diff --git a/src/datatype/function.rs b/src/datatype/function.rs index 3e57507..7d074cb 100644 --- a/src/datatype/function.rs +++ b/src/datatype/function.rs @@ -18,7 +18,7 @@ pub unsafe fn get_rs_value_from_pointer( ) -> RsArgsValue { match type_desc { RsArgsValue::I32(number) => { - let data = match number.to_basic_data_type() { + let data = match (*number).try_into().unwrap() { BasicDataType::U8 => RsArgsValue::U8(*(pointer as *mut u8)), BasicDataType::I16 => RsArgsValue::I16(*(pointer as *mut i16)), BasicDataType::I32 => RsArgsValue::I32(*(pointer as *mut i32)), diff --git a/src/datatype/pointer.rs b/src/datatype/pointer.rs index 29495a5..fede255 100644 --- a/src/datatype/pointer.rs +++ b/src/datatype/pointer.rs @@ -57,7 +57,7 @@ unsafe fn free_struct_memory( continue; } if let RsArgsValue::I32(number) = val { - let data_type = number.to_basic_data_type(); + let data_type = (*number).try_into().unwrap(); match data_type { BasicDataType::U8 => { let (size, align) = get_size_align::(); @@ -176,8 +176,6 @@ unsafe fn free_struct_memory( field_ptr = field_ptr.offset(padding as isize); if dynamic_array { free_dynamic_string_array(field_ptr, array_len); - } else { - // } offset += size + padding; field_size = size @@ -193,8 +191,6 @@ unsafe fn free_struct_memory( field_ptr = field_ptr.offset(padding as isize); if dynamic_array { free_dynamic_double_array(field_ptr, array_len); - } else { - // } offset += size + padding; field_size = size @@ -210,8 +206,6 @@ unsafe fn free_struct_memory( field_ptr = field_ptr.offset(padding as isize); if dynamic_array { free_dynamic_float_array(field_ptr, array_len); - } else { - // } offset += size + padding; field_size = size @@ -267,6 +261,7 @@ unsafe fn free_struct_memory( let (size, align) = calculate_struct_size(&obj); let padding = (align - (offset % align)) % align; field_ptr = field_ptr.offset(padding as isize); + free_struct_memory(field_ptr, obj, ptr_type); offset += size + padding; field_size = size } else { @@ -290,7 +285,7 @@ pub unsafe fn free_rs_pointer_memory( ) { match ptr_desc { RsArgsValue::I32(number) => { - let basic_data_type = number.to_basic_data_type(); + let basic_data_type = (*number).try_into().unwrap(); match basic_data_type { BasicDataType::String => { let _ = CString::from_raw(*(ptr as *mut *mut c_char)); @@ -365,7 +360,7 @@ pub unsafe fn free_c_pointer_memory( ) { match ptr_desc { RsArgsValue::I32(number) => { - let basic_data_type = number.to_basic_data_type(); + let basic_data_type = (*number).try_into().unwrap(); match basic_data_type { BasicDataType::String => { free(*(ptr as *mut *mut i8) as *mut c_void); diff --git a/src/datatype/restore_struct.rs b/src/datatype/restore_struct.rs index 8960a8a..7bc794b 100644 --- a/src/datatype/restore_struct.rs +++ b/src/datatype/restore_struct.rs @@ -26,7 +26,7 @@ pub unsafe fn create_rs_struct_from_pointer( } if let RsArgsValue::I32(number) = val { let field = field.clone(); - match number.to_basic_data_type() { + match (*number).try_into().unwrap() { BasicDataType::U8 => { let (size, align) = get_size_align::(); let padding = (align - (offset % align)) % align; diff --git a/src/define.rs b/src/define.rs index 56aed46..998286e 100644 --- a/src/define.rs +++ b/src/define.rs @@ -9,7 +9,11 @@ use napi::{Env, JsExternal, JsObject, JsUnknown}; use std::collections::HashMap; use std::hash::Hash; use std::rc::Rc; +use strum_macros::{EnumIter, FromRepr}; +type StandardResult = std::result::Result; + +#[derive(Debug)] pub enum FFIError { NapiError(Error), UnExpectedError, @@ -94,7 +98,7 @@ pub struct FFIFUNCDESC { } #[napi] -#[derive(Debug)] +#[derive(Debug, FromRepr)] pub enum DataType { String = 0, I32 = 1, @@ -115,8 +119,7 @@ pub enum DataType { BigInt = 16, I16 = 17, } - -#[derive(Debug)] +#[derive(Debug, FromRepr)] pub enum BasicDataType { String = 0, I32 = 1, @@ -133,7 +136,7 @@ pub enum BasicDataType { I16 = 17, } -#[derive(Debug)] +#[derive(Debug, FromRepr)] pub enum RefDataType { I32Array = 3, StringArray = 4, @@ -142,67 +145,37 @@ pub enum RefDataType { FloatArray = 13, } -pub trait ToDataType { - fn to_data_type(self) -> DataType; - fn to_basic_data_type(self) -> BasicDataType; - fn to_ref_data_type(self) -> RefDataType; -} -impl ToDataType for i32 { - fn to_data_type(self) -> DataType { - match self { - 0 => DataType::String, - 1 => DataType::I32, - 2 => DataType::Double, - 3 => DataType::I32Array, - 4 => DataType::StringArray, - 5 => DataType::DoubleArray, - 6 => DataType::Boolean, - 7 => DataType::Void, - 8 => DataType::I64, - 9 => DataType::U8, - 10 => DataType::U8Array, - 11 => DataType::External, - 12 => DataType::U64, - 13 => DataType::FloatArray, - 14 => DataType::Float, - 15 => DataType::WString, - 16 => DataType::BigInt, - 17 => DataType::I16, - _ => panic!("unknow DataType"), - } +impl TryFrom for DataType { + type Error = FFIError; + fn try_from(value: i32) -> StandardResult { + DataType::from_repr(value as usize).ok_or(FFIError::UnsupportedValueType(format!( + "Invalid DataType value: {}", + value + ))) } - fn to_basic_data_type(self) -> BasicDataType { - if is_array_type(&self) { - panic!( +} + +impl TryFrom for BasicDataType { + type Error = FFIError; + fn try_from(value: i32) -> StandardResult { + if let Ok(_) = value.try_into() as StandardResult { + return Err(FFIError::UnsupportedValueType(format!( "In the latest ffi-rs version, please use ffi-rs.arrayConstrutor to describe array type" - ) - } - match self { - 0 => BasicDataType::String, - 1 => BasicDataType::I32, - 2 => BasicDataType::Double, - 6 => BasicDataType::Boolean, - 7 => BasicDataType::Void, - 8 => BasicDataType::I64, - 9 => BasicDataType::U8, - 11 => BasicDataType::External, - 12 => BasicDataType::U64, - 14 => BasicDataType::Float, - 15 => BasicDataType::WString, - 16 => BasicDataType::BigInt, - 17 => BasicDataType::I16, - _ => panic!("unknow DataType"), + ))); } + BasicDataType::from_repr(value as usize).ok_or(FFIError::UnsupportedValueType(format!( + "Invalid BasicDataType value: {}", + value + ))) } - fn to_ref_data_type(self) -> RefDataType { - match self { - 3 => RefDataType::I32Array, - 4 => RefDataType::StringArray, - 5 => RefDataType::DoubleArray, - 10 => RefDataType::U8Array, - 13 => RefDataType::FloatArray, - _ => panic!("unknow DataType"), - } +} +impl TryFrom for RefDataType { + type Error = FFIError; + fn try_from(value: i32) -> StandardResult { + RefDataType::from_repr(value as usize).ok_or(FFIError::UnsupportedValueType(format!( + "Invalid RefDataType value: {}", + value + ))) } } use libffi::middle::Type; @@ -214,7 +187,7 @@ impl RsArgsTrait for RsArgsValue { fn to_ffi_type(&self) -> Type { match self { RsArgsValue::I32(number) => { - let data_type = number.to_basic_data_type(); + let data_type = (*number).try_into().unwrap(); match data_type { BasicDataType::String => Type::pointer(), BasicDataType::WString => Type::pointer(), @@ -235,13 +208,6 @@ impl RsArgsTrait for RsArgsValue { } } -pub fn is_array_type(value: &i32) -> bool { - match value { - 3 | 4 | 5 | 10 | 13 => true, - _ => false, - } -} - pub enum RsArgsValue { String(String), WString(String), diff --git a/src/lib.rs b/src/lib.rs index ffd8a89..5535600 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -231,7 +231,7 @@ unsafe fn load(env: Env, params: FFIParams) -> napi::Result { ) -> *mut ffi_type { match ret_type_rs { RsArgsValue::I32(number) => { - let ret_data_type = number.to_basic_data_type(); + let ret_data_type = (*number).try_into().unwrap(); match ret_data_type { BasicDataType::U8 => &mut ffi_type_uint8 as *mut ffi_type, BasicDataType::I32 => &mut ffi_type_sint32 as *mut ffi_type, diff --git a/src/utils/dataprocess.rs b/src/utils/dataprocess.rs index d83c872..78dbb1e 100644 --- a/src/utils/dataprocess.rs +++ b/src/utils/dataprocess.rs @@ -67,7 +67,7 @@ pub fn get_array_desc(obj: &IndexMap) -> FFIARRARYDESC { if let RsArgsValue::I32(number) = obj.get(ARRAY_TYPE_TAG).unwrap() { array_type = *number } - let array_type = array_type.to_ref_data_type(); + let array_type = array_type.try_into().unwrap(); FFIARRARYDESC { array_len, @@ -106,7 +106,7 @@ pub unsafe fn get_arg_types_values( .map(|(param, value)| { let res = match param { RsArgsValue::I32(number) => { - let param_data_type = number.to_basic_data_type(); + let param_data_type = (*number).try_into()?; match param_data_type { BasicDataType::U8 => { let arg_type = &mut ffi_type_sint32 as *mut ffi_type; @@ -527,7 +527,7 @@ pub unsafe fn get_params_value_rs_struct( let field = field.clone(); match field_type.clone() { RsArgsValue::I32(data_type_number) => { - let data_type: DataType = data_type_number.to_data_type(); + let data_type: DataType = data_type_number.try_into()?; let val = match data_type { DataType::String => { let val: JsString = params_value_object.get_named_property(&field)?; @@ -760,7 +760,7 @@ pub unsafe fn get_js_unknown_from_pointer( ) -> Result { match ret_type_rs { RsArgsValue::I32(number) => { - let ret_data_type = number.to_basic_data_type(); + let ret_data_type = (*number).try_into()?; match ret_data_type { BasicDataType::String => { let ptr_str = CStr::from_ptr(*(ptr as *mut *const c_char)) @@ -848,7 +848,7 @@ pub unsafe fn get_js_unknown_from_pointer( unsafe fn write_rs_ptr_to_c(ret_type: &RsArgsValue, src: *mut c_void, dst: *mut c_void) { match &ret_type { RsArgsValue::I32(number) => { - let ret_data_type = number.to_basic_data_type(); + let ret_data_type = (*number).try_into().unwrap(); match ret_data_type { BasicDataType::U8 => std::ptr::copy(src, dst, std::mem::size_of::()), BasicDataType::I16 => std::ptr::copy(src, dst, std::mem::size_of::()), diff --git a/src/utils/object_utils.rs b/src/utils/object_utils.rs index 2875222..ecb490a 100644 --- a/src/utils/object_utils.rs +++ b/src/utils/object_utils.rs @@ -40,8 +40,8 @@ pub fn calculate_struct_size(struct_type: &IndexMap) -> (us if field_name == FFI_TAG_FIELD { return (size, align, offset); } - if let RsArgsValue::I32(number) = field_type { - return match number.to_basic_data_type() { + if let RsArgsValue::I32(field_type_number) = field_type { + return match (*field_type_number).try_into().unwrap() { BasicDataType::U8 => calculate_u8(size, align, offset), BasicDataType::I16 => calculate_i16(size, align, offset), BasicDataType::I32 => calculate_i32(size, align, offset),