From 9e9aa282b10c5dd1c3e5480c8defc91df333bed6 Mon Sep 17 00:00:00 2001 From: yyc12345 Date: Mon, 11 May 2026 13:54:47 +0800 Subject: [PATCH] feat: use macro to simplify cdylib decl --- wfassoc-cdylib/src/lib.rs | 163 +++++++++++++++++++++++++------------- 1 file changed, 107 insertions(+), 56 deletions(-) diff --git a/wfassoc-cdylib/src/lib.rs b/wfassoc-cdylib/src/lib.rs index 35288b3..1386485 100644 --- a/wfassoc-cdylib/src/lib.rs +++ b/wfassoc-cdylib/src/lib.rs @@ -74,6 +74,103 @@ macro_rules! pull_writer { }; } +/// Macro to wrap inner function execution with standard error handling pattern. +/// +/// For functions with no output parameter and no input parameters: +/// ```ignore +/// cffi_wrapper!(|| { +/// // inner function body returning Result<()> +/// }); +/// ``` +/// +/// For functions with no output parameter and with input parameters: +/// ```ignore +/// cffi_wrapper!(|param1: Type1, param2: Type2| { +/// // inner function body using param1, param2 returning Result<()> +/// }); +/// ``` +/// +/// For functions with one output parameter and no input parameters: +/// ```ignore +/// cffi_wrapper!(|| -> (out_param, OutType) { +/// // inner function body returning Result +/// }); +/// ``` +/// +/// For functions with one output parameter and with input parameters: +/// ```ignore +/// cffi_wrapper!(|param1: Type1| -> (out_param, OutType) { +/// // inner function body using param1 returning Result +/// }); +/// ``` +macro_rules! cffi_wrapper { + // Case with output parameter and input parameters + (|$($param:ident: $param_ty:ty),*| -> ($out_param:ident: $out_param_ty:ty) $inner_body:block) => {{ + fn inner($($param: $param_ty),*) -> Result<$out_param_ty> $inner_body + + match inner($($param),*) { + Ok(rv) => { + set_out_param!($out_param, rv); + last_error::clear_last_error(); + true + } + Err(e) => { + last_error::set_last_error(e.to_string().as_str()); + false + } + } + }}; + + // Case with output parameter and no input parameters + (|| -> ($out_param:ident: $out_param_ty:ty) $inner_body:block) => {{ + fn inner() -> Result<$out_param_ty> $inner_body + + match inner() { + Ok(rv) => { + set_out_param!($out_param, rv); + last_error::clear_last_error(); + true + } + Err(e) => { + last_error::set_last_error(e.to_string().as_str()); + false + } + } + }}; + + // Case without output parameter but with input parameters + (|$($param:ident: $param_ty:ty),*| $inner_body:block) => {{ + fn inner($($param: $param_ty),*) -> Result<()> $inner_body + + match inner($($param),*) { + Ok(_) => { + last_error::clear_last_error(); + true + } + Err(e) => { + last_error::set_last_error(e.to_string().as_str()); + false + } + } + }}; + + // Case without output parameter and no input parameters + ($inner_body:block) => {{ + fn inner() -> Result<()> $inner_body + + match inner() { + Ok(_) => { + last_error::clear_last_error(); + true + } + Err(e) => { + last_error::set_last_error(e.to_string().as_str()); + false + } + } + }}; +} + // endregion // region: Exposed Functions @@ -111,22 +208,10 @@ static SCHEMA_POOL: LazyLock>> = #[unsafe(no_mangle)] pub extern "C" fn WFSchemaCreate(out_schema: out_param_ty!(Token)) -> bool { - fn inner() -> Result { + cffi_wrapper!(|| -> (out_schema: Token) { let mut pool = pull_writer!(SCHEMA_POOL)?; Ok(pool.allocate(Schema::new())?) - } - - match inner() { - Ok(rv) => { - set_out_param!(out_schema, rv); - last_error::clear_last_error(); - true - } - Err(e) => { - last_error::set_last_error(e.to_string().as_str()); - false - } - } + }) } #[unsafe(no_mangle)] @@ -134,23 +219,12 @@ pub extern "C" fn WFSchemaSetIdentifier( in_schema: in_param_ty!(Token), in_value: in_param_ty!(CStyleString), ) -> bool { - fn inner(in_schema: Token, in_value: CStyleString) -> Result<()> { + cffi_wrapper!(|in_schema: Token, in_value: CStyleString| { let mut pool = pull_writer!(SCHEMA_POOL)?; let schema = pool.get_mut(in_schema)?; schema.set_identifier(cstr_ffi::parse_ffi_string(in_value)?); Ok(()) - } - - match inner(in_schema, in_value) { - Ok(_) => { - last_error::clear_last_error(); - true - } - Err(e) => { - last_error::set_last_error(e.to_string().as_str()); - false - } - } + }) } #[unsafe(no_mangle)] @@ -158,45 +232,22 @@ pub extern "C" fn WFSchemaIntoProgram( in_schema: in_param_ty!(Token), out_program: out_param_ty!(Token), ) -> bool { - fn inner(in_token: Token) -> Result { + cffi_wrapper!(|in_schema: Token| -> (out_program: Token) { let mut pool = pull_writer!(SCHEMA_POOL)?; - let schema = pool.pop(in_token)?; + let schema = pool.pop(in_schema)?; let mut pool = pull_writer!(PROGRAM_POOL)?; let program = schema.into_program()?; Ok(pool.allocate(program)?) - } - - match inner(in_schema) { - Ok(rv) => { - set_out_param!(out_program, rv); - last_error::clear_last_error(); - true - } - Err(e) => { - last_error::set_last_error(e.to_string().as_str()); - false - } - } + }) } #[unsafe(no_mangle)] pub extern "C" fn WFSchemaDestroy(in_schema: in_param_ty!(Token)) -> bool { - fn inner(in_token: Token) -> Result<()> { + cffi_wrapper!(|in_schema: Token| { let mut pool = pull_writer!(SCHEMA_POOL)?; - Ok(pool.free(in_token)?) - } - - match inner(in_schema) { - Ok(_) => { - last_error::clear_last_error(); - true - } - Err(e) => { - last_error::set_last_error(e.to_string().as_str()); - false - } - } + Ok(pool.free(in_schema)?) + }) } // endregion