feat: csharp bindings

This commit is contained in:
Stefan
2024-08-15 18:02:10 +02:00
parent aa08c73f2b
commit 5e98e3340d
4 changed files with 199 additions and 3 deletions
+6 -3
View File
@@ -17,11 +17,14 @@ zen-expression = { path = "../../core/expression" }
zen-tmpl = { path = "../../core/template" }
[lib]
crate-type = ["staticlib"]
crate-type = ["cdylib"]
[build-dependencies]
cbindgen = "0.26.0"
cbindgen = "0.27.0"
csbindgen = "1.9.3"
glob = "0.3.1"
[features]
default = ["go"]
default = ["csharp"]
csharp = []
go = []
+140
View File
@@ -0,0 +1,140 @@
// <auto-generated>
// This code is generated by csbindgen.
// DON'T CHANGE THIS DIRECTLY.
// </auto-generated>
#pragma warning disable CS8500
#pragma warning disable CS8981
using System;
using System.Runtime.InteropServices;
namespace GoRules.Zen
{
internal static unsafe partial class ZenFfi
{
const string __DllName = "libzen_ffi";
/// <summary>
/// Frees ZenDecision
/// </summary>
[DllImport(__DllName, EntryPoint = "zen_decision_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
internal static extern void zen_decision_free(ZenDecisionStruct* decision);
/// <summary>
/// Evaluates ZenDecision
/// Caller is responsible for freeing context and ZenResult.
/// </summary>
[DllImport(__DllName, EntryPoint = "zen_decision_evaluate", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
internal static extern ZenResult zen_decision_evaluate(ZenDecisionStruct* decision, byte* context_ptr, ZenEngineEvaluationOptions options);
/// <summary>
/// Create a new ZenEngine instance, caller is responsible for freeing the returned reference
/// by calling zen_engine_free.
/// </summary>
[DllImport(__DllName, EntryPoint = "zen_engine_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
internal static extern ZenEngineStruct* zen_engine_new();
/// <summary>
/// Frees the ZenEngine instance reference from the memory
/// </summary>
[DllImport(__DllName, EntryPoint = "zen_engine_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
internal static extern void zen_engine_free(ZenEngineStruct* engine);
/// <summary>
/// Creates a Decision using a reference of DecisionEngine and content (JSON)
/// Caller is responsible for freeing content and ZenResult.
/// </summary>
[DllImport(__DllName, EntryPoint = "zen_engine_create_decision", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
internal static extern ZenResult zen_engine_create_decision(ZenEngineStruct* engine, byte* content);
/// <summary>
/// Evaluates rules engine using a DecisionEngine reference via loader
/// Caller is responsible for freeing: key, context and ZenResult.
/// </summary>
[DllImport(__DllName, EntryPoint = "zen_engine_evaluate", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
internal static extern ZenResult zen_engine_evaluate(ZenEngineStruct* engine, byte* key, byte* context, ZenEngineEvaluationOptions options);
/// <summary>
/// Loads a Decision through DecisionEngine
/// Caller is responsible for freeing: key and ZenResult.
/// </summary>
[DllImport(__DllName, EntryPoint = "zen_engine_get_decision", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
internal static extern ZenResult zen_engine_get_decision(ZenEngineStruct* engine, byte* key);
[DllImport(__DllName, EntryPoint = "zen_evaluate_expression", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
internal static extern ZenResult zen_evaluate_expression(byte* expression, byte* context);
/// <summary>
/// Evaluate unary expression, responsible for freeing expression and context
/// True = 1
/// False = 0
/// </summary>
[DllImport(__DllName, EntryPoint = "zen_evaluate_unary_expression", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
internal static extern ZenResult zen_evaluate_unary_expression(byte* expression, byte* context);
/// <summary>
/// Evaluate unary expression, responsible for freeing expression and context
/// True = 1
/// False = 0
/// </summary>
[DllImport(__DllName, EntryPoint = "zen_evaluate_template", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
internal static extern ZenResult zen_evaluate_template(byte* template, byte* context);
/// <summary>
/// Creates a new ZenEngine instance with loader, caller is responsible for freeing the returned reference
/// by calling zen_engine_free.
/// </summary>
[DllImport(__DllName, EntryPoint = "zen_engine_new_native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
internal static extern ZenEngineStruct* zen_engine_new_native(delegate* unmanaged[Cdecl]<byte*, ZenDecisionLoaderResult> loader_callback, delegate* unmanaged[Cdecl]<byte*, ZenCustomNodeResult> custom_node_callback);
}
[StructLayout(LayoutKind.Sequential)]
internal unsafe partial struct ZenCustomNodeResult
{
public byte* content;
public byte* error;
}
[StructLayout(LayoutKind.Sequential)]
internal unsafe partial struct ZenDecisionStruct
{
public fixed byte _data[1];
public PhantomData _marker;
}
[StructLayout(LayoutKind.Sequential)]
internal unsafe partial struct ZenEngineStruct
{
public fixed byte _data[1];
public PhantomData _marker;
}
[StructLayout(LayoutKind.Sequential)]
internal unsafe partial struct ZenEngineEvaluationOptions
{
[MarshalAs(UnmanagedType.U1)] public bool trace;
public byte max_depth;
}
[StructLayout(LayoutKind.Sequential)]
internal unsafe partial struct ZenDecisionLoaderResult
{
public byte* content;
public byte* error;
}
[StructLayout(LayoutKind.Sequential)]
internal unsafe partial struct ZenResult
{
public T* result;
public byte error;
public byte* details;
}
}
+27
View File
@@ -0,0 +1,27 @@
[package]
name = "zen-ffi"
version = "0.1.0"
edition = "2021"
license = "MIT"
publish = false
[dependencies]
anyhow = { workspace = true }
libc = "0.2.155"
serde = { workspace = true }
serde_json = { workspace = true }
strum = { workspace = true, features = ["derive"] }
tokio = { workspace = true, features = ["rt"] }
zen-engine = { path = "../../core/engine" }
zen-expression = { path = "../../core/expression" }
zen-tmpl = { path = "../../core/template" }
[lib]
crate-type = ["staticlib"]
[build-dependencies]
cbindgen = "0.26.0"
[features]
default = ["go"]
go = []
+26
View File
@@ -1,4 +1,5 @@
use std::env;
use std::path::PathBuf;
fn main() {
let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
@@ -9,4 +10,29 @@ fn main() {
.generate()
.expect("Unable to generate bindings")
.write_to_file("zen_engine.h");
#[cfg(feature = "csharp")]
{
let rust_files: Vec<PathBuf> = glob::glob("src/**/*.rs")
.unwrap()
.map(|s| s.unwrap())
.collect();
let valid_rust_files: Vec<PathBuf> = rust_files
.into_iter()
.filter(|p| !p.ends_with("languages/go.rs"))
.collect();
let mut cs_builder = csbindgen::Builder::default();
for p in valid_rust_files.into_iter() {
cs_builder = cs_builder.input_extern_file(p.to_str().unwrap().to_string())
}
cs_builder
.csharp_dll_name("libzen_ffi")
.csharp_namespace("GoRules.Zen")
.csharp_class_name("ZenFfi")
.generate_csharp_file("ZenFfi.g.cs")
.unwrap();
}
}