From f0e610f8c82c6a9e4aae3d5edf055095b13caf03 Mon Sep 17 00:00:00 2001 From: yyc12345 Date: Sun, 10 May 2026 23:16:56 +0800 Subject: [PATCH] feat: add example for cdylib --- wfassoc-cdylib/src/lib.rs | 114 +++++++++++++++++++++++++++--- wfassoc-cdylib/src/object_pool.rs | 9 ++- wfassoc-cdylib/src/wrapper.rs | 83 ---------------------- 3 files changed, 112 insertions(+), 94 deletions(-) delete mode 100644 wfassoc-cdylib/src/wrapper.rs diff --git a/wfassoc-cdylib/src/lib.rs b/wfassoc-cdylib/src/lib.rs index bd01077..e0a98b4 100644 --- a/wfassoc-cdylib/src/lib.rs +++ b/wfassoc-cdylib/src/lib.rs @@ -1,11 +1,14 @@ - -use std::ffi::{CString, c_char}; -use thiserror::Error as TeError; - -mod object_pool; -mod last_error; mod cstr_ffi; -mod wrapper; +mod last_error; +mod object_pool; + +use object_pool::ObjectPool; +use std::ffi::{CString, c_char}; +use std::sync::{LazyLock, PoisonError, RwLock}; +use thiserror::Error as TeError; +use wfassoc::highlevel::{Program, Schema}; + +pub use object_pool::Token; // region: Error @@ -25,6 +28,13 @@ enum Error { /// Error when manipulating with C-style string. #[error("{0}")] CStrFfi(#[from] cstr_ffi::Error), + /// Error when manipulating with object pool. + #[error("{0}")] + ObjectPool(#[from] object_pool::Error), + + /// Error when manipulating with poison RwLock + #[error("RwLock is poisoning")] + PoisonRwLock, } /// Result type used in this crate. @@ -34,9 +44,12 @@ type Result = std::result::Result; // region: Macros - // endregion +// region: Exposed Functions + +// region: Facilities + #[unsafe(no_mangle)] pub extern "C" fn WFStartup() -> bool { true @@ -59,6 +72,89 @@ pub extern "C" fn WFHasPrivilege() -> bool { #[unsafe(no_mangle)] pub extern "C" fn WFAdd(left: u32, right: u32, rv: *mut u32) -> bool { - unsafe { *rv = left + right; } + unsafe { + *rv = left + right; + } return true; } + +// endregion + +// region: Schema + +const SCHEMA_POOL: LazyLock>> = + LazyLock::new(|| RwLock::new(ObjectPool::new())); + +#[unsafe(no_mangle)] +pub extern "C" fn WFSchemaCreate(out_token: *mut Token) -> bool { + fn inner() -> Result { + let binding = &SCHEMA_POOL; + let mut pool = binding.write().map_err(|_| Error::PoisonRwLock)?; + Ok(pool.allocate(Schema::new())?) + } + + match inner() { + Ok(rv) => { + unsafe { *out_token = rv }; + true + } + Err(e) => { + last_error::set_last_error(e.to_string().as_str()); + false + } + } +} + + +#[unsafe(no_mangle)] +pub extern "C" fn WFSchemaIntoProgram(in_token: Token, out_token: *mut Token) -> bool { + fn inner(in_token: Token) -> Result { + let binding = &SCHEMA_POOL; + let mut pool = binding.write().map_err(|_| Error::PoisonRwLock)?; + let schema = pool.pop(in_token)?; + + let binding = &PROGRAM_POOL; + let mut pool = binding.write().map_err(|_| Error::PoisonRwLock)?; + let program = schema.into_program()?; + Ok(pool.allocate(program)?) + } + + match inner(in_token) { + Ok(rv) => { + unsafe { *out_token = rv }; + true + } + Err(e) => { + last_error::set_last_error(e.to_string().as_str()); + false + } + } +} + +#[unsafe(no_mangle)] +pub extern "C" fn WFSchemaDestroy(in_token: Token) -> bool { + fn inner(in_token: Token) -> Result<()> { + let binding = &SCHEMA_POOL; + let mut pool = binding.write().map_err(|_| Error::PoisonRwLock)?; + Ok(pool.free(in_token)?) + } + + match inner(in_token) { + Ok(_) => true, + Err(e) => { + last_error::set_last_error(e.to_string().as_str()); + false + } + } +} + +// endregion + +// region: Program + +const PROGRAM_POOL: LazyLock>> = + LazyLock::new(|| RwLock::new(ObjectPool::new())); + +// endregion + +// endregion diff --git a/wfassoc-cdylib/src/object_pool.rs b/wfassoc-cdylib/src/object_pool.rs index 94048cf..60fe641 100644 --- a/wfassoc-cdylib/src/object_pool.rs +++ b/wfassoc-cdylib/src/object_pool.rs @@ -44,9 +44,14 @@ impl ObjectPool { Ok(Self::key_to_token(&key)) } - pub fn delete(&mut self, token: Token) -> Result<(), Error> { + pub fn free(&mut self, token: Token) -> Result<(), Error> { + let _ = self.pop(token)?; + Ok(()) + } + + pub fn pop(&mut self, token: Token) -> Result { match self.objs.remove(Self::token_to_key(token)) { - Some(_) => Ok(()), + Some(obj) => Ok(obj), None => Err(Error::NoSuchToken), } } diff --git a/wfassoc-cdylib/src/wrapper.rs b/wfassoc-cdylib/src/wrapper.rs deleted file mode 100644 index d7dca53..0000000 --- a/wfassoc-cdylib/src/wrapper.rs +++ /dev/null @@ -1,83 +0,0 @@ -use std::collections::HashMap; - -use thiserror::Error as TeError; - -/// Error occurs in this module. -#[derive(Debug, TeError)] -pub enum Error {} - -/// Result type used in this module. -type Result = std::result::Result; - -/// Schema is the sketchpad of complete Program. -/// -/// We will create a Schema first, fill some properties, add file extensions, -/// then convert it into immutable Program for following using. -#[derive(Debug)] -pub struct Schema { - identifier: String, - path: String, - clsid: String, - icons: HashMap, - behaviors: HashMap, - exts: HashMap, -} - -/// Internal used struct as the Schema file extensions hashmap value type. -#[derive(Debug)] -struct SchemaExt { - name: String, - icon: String, - behavior: String, -} - -impl Schema { - pub fn new() -> Self { - Self { - identifier: String::new(), - path: String::new(), - clsid: String::new(), - icons: HashMap::new(), - behaviors: HashMap::new(), - exts: HashMap::new(), - } - } - - pub fn set_identifier(&mut self, identifier: &str) -> Result<()> {} - - pub fn set_path(&mut self, exe_path: &str) -> Result<()> {} - - pub fn set_clsid(&mut self, clsid: &str) -> Result<()> {} - - pub fn add_icon(&mut self, name: &str, value: &str) -> Result<()> {} - - pub fn add_behavior(&mut self, name: &str, value: &str) -> Result<()> {} - - pub fn add_ext( - &mut self, - ext: &str, - ext_name: &str, - ext_icon: &str, - ext_behavior: &str, - ) -> Result<()> { - } - - pub fn into_program(self) -> Result { - Program::new(self) - } -} - -/// Program is a complete and immutable program representer -pub struct Program {} - -impl TryFrom for Program { - type Error = Error; - - fn try_from(value: Schema) -> std::result::Result { - Self::new(value) - } -} - -impl Program { - pub fn new(schema: Schema) -> Result {} -}