From ba2bfa7651bf228197be998f29231acc98348796 Mon Sep 17 00:00:00 2001 From: Stefan Date: Thu, 10 Aug 2023 19:05:07 +0200 Subject: [PATCH] fix: binding fixes --- bindings/c/Cargo.toml | 8 ++++---- bindings/c/src/bindings.rs | 16 +++++++--------- bindings/c/src/helpers/types.rs | 32 +++++++++++++++++++++----------- bindings/c/src/languages/go.rs | 14 +++++++------- bindings/c/src/languages/mod.rs | 4 +++- bindings/c/src/loader.rs | 1 + bindings/c/test.c | 11 +++++++++++ 7 files changed, 54 insertions(+), 32 deletions(-) create mode 100644 bindings/c/test.c diff --git a/bindings/c/Cargo.toml b/bindings/c/Cargo.toml index 49afd442..d1fec5e3 100644 --- a/bindings/c/Cargo.toml +++ b/bindings/c/Cargo.toml @@ -5,9 +5,6 @@ edition = "2021" license = "MIT" publish = false -[lib] -crate-type = ["staticlib"] - [dependencies] async-trait = { workspace = true } anyhow = { workspace = true } @@ -17,4 +14,7 @@ futures = "0.3.28" zen-engine = { path = "../../core/engine" } [build-dependencies] -cbindgen = "0.24.0" \ No newline at end of file +cbindgen = "0.24.0" + +[features] +cdylib = [] \ No newline at end of file diff --git a/bindings/c/src/bindings.rs b/bindings/c/src/bindings.rs index 82515d09..0c6ee12d 100644 --- a/bindings/c/src/bindings.rs +++ b/bindings/c/src/bindings.rs @@ -1,23 +1,21 @@ use crate::helpers::result::CResult; use crate::helpers::types::{ CZenDecision, CZenDecisionEngine, CZenDecisionEnginePtr, CZenDecisionPtr, - CZenEngineEvaluationOptions, DynDecisionLoader, + CZenEngineEvaluationOptions, DynamicDecisionLoader, }; use crate::loader::{CDecisionLoader, CZenDecisionLoaderCallback}; use futures::executor::block_on; use serde_json::Value; -use std::ffi::{c_char, c_void, CStr, CString}; +use std::ffi::{c_char, CStr, CString}; use std::sync::Arc; -use zen_engine::loader::NoopLoader; use zen_engine::model::DecisionContent; use zen_engine::DecisionEngine; /// Create a new DecisionEngine instance, caller is responsible for freeing the returned reference #[no_mangle] pub extern "C" fn zen_engine_new() -> *mut CZenDecisionEnginePtr { - let loader = Arc::new(NoopLoader::default()); - let engine: CZenDecisionEngine = DecisionEngine::new(DynDecisionLoader::new(loader)); + let engine: CZenDecisionEngine = DecisionEngine::new(DynamicDecisionLoader::default()); Box::into_raw(Box::new(engine)) as *mut CZenDecisionEnginePtr } @@ -27,8 +25,8 @@ pub extern "C" fn zen_engine_new() -> *mut CZenDecisionEnginePtr { pub extern "C" fn zen_engine_new_with_loader( callback: CZenDecisionLoaderCallback, ) -> *mut CZenDecisionEnginePtr { - let loader = Arc::new(CDecisionLoader::new(callback)); - let engine: CZenDecisionEngine = DecisionEngine::new(DynDecisionLoader::new(loader)); + let loader = CDecisionLoader::new(callback); + let engine: CZenDecisionEngine = DecisionEngine::new(DynamicDecisionLoader::Native(loader)); Box::into_raw(Box::new(engine)) as *mut CZenDecisionEnginePtr } @@ -38,7 +36,7 @@ pub extern "C" fn zen_engine_new_with_loader( pub extern "C" fn zen_engine_free(engine: *mut CZenDecisionEnginePtr) { assert!(!engine.is_null()); - unsafe { Box::from_raw(engine as *mut CZenDecisionEnginePtr) }; + unsafe { Box::from_raw(engine as *mut CZenDecisionEngine) }; } /// Creates a Decision using a reference of DecisionEngine and content (JSON) @@ -147,7 +145,7 @@ pub extern "C" fn zen_engine_load_decision( Err(e) => return CResult::from(&e), }; - CResult::ok(Box::into_raw(Box::new(decision)) as *mut c_void) + CResult::ok(Box::into_raw(Box::new(decision)) as *mut CZenDecisionPtr) } /// Evaluates rules engine using a Decision diff --git a/bindings/c/src/helpers/types.rs b/bindings/c/src/helpers/types.rs index 6656ddaa..50725ed6 100644 --- a/bindings/c/src/helpers/types.rs +++ b/bindings/c/src/helpers/types.rs @@ -1,16 +1,17 @@ +use crate::loader::CDecisionLoader; use async_trait::async_trait; use std::ffi::c_void; -use std::sync::Arc; -use zen_engine::loader::{DecisionLoader, LoaderResponse}; +use zen_engine::loader::{DecisionLoader, LoaderResponse, NoopLoader}; use zen_engine::{Decision, DecisionEngine, EvaluationOptions}; -pub type CZenDecision = Decision; -pub type CZenDecisionEngine = DecisionEngine; +pub(crate) type CZenDecision = Decision; +pub(crate) type CZenDecisionEngine = DecisionEngine; pub type CZenDecisionPtr = c_void; pub type CZenDecisionEnginePtr = c_void; #[repr(C)] +#[derive(Debug)] pub struct CZenEngineEvaluationOptions { trace: bool, max_depth: u8, @@ -25,19 +26,28 @@ impl Into for CZenEngineEvaluationOptions { } } -pub struct DynDecisionLoader { - inner: Arc, +#[derive(Debug)] +pub(crate) enum DynamicDecisionLoader { + Noop(NoopLoader), + Native(CDecisionLoader), + #[cfg(not(feature = "cdylib"))] + Go(crate::languages::go::CGoDecisionLoader), } -impl DynDecisionLoader { - pub fn new(inner: Arc) -> Self { - Self { inner } +impl Default for DynamicDecisionLoader { + fn default() -> Self { + Self::Noop(Default::default()) } } #[async_trait] -impl DecisionLoader for DynDecisionLoader { +impl DecisionLoader for DynamicDecisionLoader { async fn load(&self, key: &str) -> LoaderResponse { - self.inner.load(key).await + match self { + DynamicDecisionLoader::Noop(loader) => loader.load(key).await, + DynamicDecisionLoader::Native(loader) => loader.load(key).await, + #[cfg(not(feature = "cdylib"))] + DynamicDecisionLoader::Go(loader) => loader.load(key).await, + } } } diff --git a/bindings/c/src/languages/go.rs b/bindings/c/src/languages/go.rs index 4585da93..39a4c09a 100644 --- a/bindings/c/src/languages/go.rs +++ b/bindings/c/src/languages/go.rs @@ -1,8 +1,7 @@ -use crate::helpers::types::{CZenDecisionEngine, CZenDecisionEnginePtr, DynDecisionLoader}; +use crate::helpers::types::{CZenDecisionEngine, CZenDecisionEnginePtr, DynamicDecisionLoader}; use crate::loader::CZenDecisionLoaderResult; use async_trait::async_trait; -use std::ffi::{c_char, CString}; -use std::sync::Arc; +use std::ffi::c_char; use zen_engine::loader::{DecisionLoader, LoaderError, LoaderResponse}; use zen_engine::DecisionEngine; @@ -11,8 +10,8 @@ use zen_engine::DecisionEngine; pub extern "C" fn zen_engine_new_with_go_loader( maybe_loader: Option<&usize>, ) -> *mut CZenDecisionEnginePtr { - let loader = Arc::new(CGoDecisionLoader::new(maybe_loader.cloned())); - let engine: CZenDecisionEngine = DecisionEngine::new(DynDecisionLoader::new(loader)); + let loader = CGoDecisionLoader::new(maybe_loader.cloned()); + let engine: CZenDecisionEngine = DecisionEngine::new(DynamicDecisionLoader::Go(loader)); Box::into_raw(Box::new(engine)) as *mut CZenDecisionEnginePtr } @@ -24,8 +23,9 @@ extern "C" { -> CZenDecisionLoaderResult; } -#[derive(Default)] +#[derive(Debug, Default)] pub(crate) struct CGoDecisionLoader { + #[allow(dead_code)] handler: Option, } @@ -42,7 +42,7 @@ impl DecisionLoader for CGoDecisionLoader { return Err(LoaderError::NotFound(key.to_string()).into()) }; - let c_key = CString::new(key).unwrap(); + let c_key = std::ffi::CString::new(key).unwrap(); let c_content_ptr = unsafe { zen_engine_go_loader_callback(handler.clone(), c_key.as_ptr()) }; diff --git a/bindings/c/src/languages/mod.rs b/bindings/c/src/languages/mod.rs index 4a07c26e..775c279a 100644 --- a/bindings/c/src/languages/mod.rs +++ b/bindings/c/src/languages/mod.rs @@ -1,2 +1,4 @@ /// Language specific bindings, loaders and helpers -mod go; + +#[cfg(not(feature = "cdylib"))] +pub(crate) mod go; diff --git a/bindings/c/src/loader.rs b/bindings/c/src/loader.rs index 315ad04e..c36c4fa0 100644 --- a/bindings/c/src/loader.rs +++ b/bindings/c/src/loader.rs @@ -53,6 +53,7 @@ impl CZenDecisionLoaderResult { } } +#[derive(Debug)] pub(crate) struct CDecisionLoader { callback: CZenDecisionLoaderCallback, } diff --git a/bindings/c/test.c b/bindings/c/test.c new file mode 100644 index 00000000..9fe54ba0 --- /dev/null +++ b/bindings/c/test.c @@ -0,0 +1,11 @@ +#include "bindings.h" + + +int main() { + while(true) { + void* engine = zen_engine_new(); + zen_engine_free(engine); + } + + return 0; +} \ No newline at end of file