mirror of
https://github.com/microsoft/regorus.git
synced 2026-08-05 02:16:11 +00:00
Bindings for C, C#, Golang (#124)
* FFI bindings Generate C FFI as well as C# FFI Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com> * Regorus C binding Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com> * C# binding Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com> * Golang binding Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com> --------- Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
This commit is contained in:
committed by
GitHub
parent
25b1ffe6d7
commit
22260ac46f
@@ -1,6 +1,7 @@
|
||||
[workspace]
|
||||
|
||||
members = [
|
||||
"bindings/ffi",
|
||||
"bindings/python",
|
||||
"bindings/wasm"
|
||||
]
|
||||
|
||||
27
bindings/c/CMakeLists.txt
Normal file
27
bindings/c/CMakeLists.txt
Normal file
@@ -0,0 +1,27 @@
|
||||
# Copyright (c) Microsoft
|
||||
# Licensed under the MIT License.
|
||||
|
||||
cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
|
||||
include(FetchContent)
|
||||
|
||||
FetchContent_Declare(
|
||||
Corrosion
|
||||
GIT_REPOSITORY https://github.com/corrosion-rs/corrosion.git
|
||||
GIT_TAG v0.4 # Optionally specify a commit hash, version tag or branch here
|
||||
)
|
||||
FetchContent_MakeAvailable(Corrosion)
|
||||
|
||||
project("regorus-test-c")
|
||||
|
||||
corrosion_import_crate(
|
||||
# Path to <regorus-source-folder>/bindings/ffi/Cargo.toml
|
||||
MANIFEST_PATH "../ffi/Cargo.toml"
|
||||
# Always build regorus in Release mode.
|
||||
PROFILE "release"
|
||||
# Only build the "regorusc" crate.
|
||||
CRATES "regorus-ffi")
|
||||
|
||||
add_executable(regorus_test main.c)
|
||||
# Add path to <regorus-source-folder>/bindings/ffi
|
||||
target_include_directories(regorus_test PRIVATE "../ffi")
|
||||
target_link_libraries(regorus_test regorus-ffi)
|
||||
55
bindings/c/main.c
Normal file
55
bindings/c/main.c
Normal file
@@ -0,0 +1,55 @@
|
||||
#include <stdio.h>
|
||||
#include "regorus.h"
|
||||
|
||||
int main() {
|
||||
// Create engine.
|
||||
RegorusEngine* engine = regorus_engine_new();
|
||||
RegorusResult r;
|
||||
|
||||
// Load policies.
|
||||
r = regorus_engine_add_policy_from_file(engine, "../../../tests/aci/framework.rego");
|
||||
if (r.status != RegorusStatusOk)
|
||||
goto error;
|
||||
regorus_result_drop(r);
|
||||
|
||||
r = regorus_engine_add_policy_from_file(engine, "../../../tests/aci/api.rego");
|
||||
if (r.status != RegorusStatusOk)
|
||||
goto error;
|
||||
regorus_result_drop(r);
|
||||
|
||||
r = regorus_engine_add_policy_from_file(engine, "../../../tests/aci/policy.rego");
|
||||
if (r.status != RegorusStatusOk)
|
||||
goto error;
|
||||
regorus_result_drop(r);
|
||||
|
||||
// Add data
|
||||
r = regorus_engine_add_data_from_json_file(engine, "../../../tests/aci/data.json");
|
||||
if (r.status != RegorusStatusOk)
|
||||
goto error;
|
||||
regorus_result_drop(r);
|
||||
|
||||
// Set input
|
||||
r = regorus_engine_set_input_from_json_file(engine, "../../../tests/aci/input.json");
|
||||
if (r.status != RegorusStatusOk)
|
||||
goto error;
|
||||
regorus_result_drop(r);
|
||||
|
||||
// Eval query
|
||||
r = regorus_engine_eval_query(engine, "data.framework.mount_overlay=x");
|
||||
if (r.status != RegorusStatusOk)
|
||||
goto error;
|
||||
|
||||
// Print output
|
||||
printf("%s", r.output);
|
||||
regorus_result_drop(r);
|
||||
|
||||
|
||||
// Free the engine.
|
||||
regorus_engine_drop(engine);
|
||||
|
||||
return 0;
|
||||
error:
|
||||
printf("%s", r.error_message);
|
||||
|
||||
return 1;
|
||||
}
|
||||
51
bindings/csharp/Program.cs
Normal file
51
bindings/csharp/Program.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System.Diagnostics;
|
||||
|
||||
long nanosecPerTick = (1000L*1000L*1000L) / Stopwatch.Frequency;
|
||||
var w = new Stopwatch();
|
||||
|
||||
|
||||
// Force load of modules.
|
||||
{
|
||||
var _e = new Regorus.Engine();
|
||||
var _j = System.Text.Json.JsonDocument.Parse("{}");
|
||||
}
|
||||
|
||||
w.Restart();
|
||||
|
||||
var engine = new Regorus.Engine();
|
||||
|
||||
w.Stop();
|
||||
var newEngineTicks = w.ElapsedTicks;
|
||||
|
||||
|
||||
w.Restart();
|
||||
|
||||
// Load policies and data.
|
||||
engine.AddPolicyFromFile("../../tests/aci/framework.rego");
|
||||
engine.AddPolicyFromFile("../../tests/aci/api.rego");
|
||||
engine.AddPolicyFromFile("../../tests/aci/policy.rego");
|
||||
engine.AddDataFromJsonFile("../../tests/aci/data.json");
|
||||
|
||||
|
||||
w.Stop();
|
||||
var loadPoliciesTicks = w.ElapsedTicks;
|
||||
|
||||
|
||||
w.Restart();
|
||||
|
||||
// Set input and eval query.
|
||||
engine.SetInputFromJsonFile("../../tests/aci/input.json");
|
||||
var results = engine.EvalQuery("data.framework.mount_overlay = x");
|
||||
var resultsDoc = System.Text.Json.JsonDocument.Parse(results);
|
||||
|
||||
w.Stop();
|
||||
var evalTicks = w.ElapsedTicks;
|
||||
|
||||
Console.WriteLine("{0}", results);
|
||||
|
||||
|
||||
Console.WriteLine("Engine creation took {0} msecs", (newEngineTicks*nanosecPerTick)/(1000.0*1000.0));
|
||||
Console.WriteLine("Load policies and data took {0} msecs", (loadPoliciesTicks*nanosecPerTick)/(1000.0*1000.0));
|
||||
Console.WriteLine("EvalQuery took {0} msecs", (evalTicks*nanosecPerTick)/(1000.0*1000.0));
|
||||
|
||||
|
||||
169
bindings/csharp/Regorus.cs
Normal file
169
bindings/csharp/Regorus.cs
Normal file
@@ -0,0 +1,169 @@
|
||||
using System.Text;
|
||||
|
||||
namespace Regorus
|
||||
{
|
||||
public class Exception : System.Exception
|
||||
{
|
||||
public Exception(string? message) : base(message) {}
|
||||
}
|
||||
|
||||
public class Engine : ICloneable
|
||||
{
|
||||
unsafe private RegorusFFI.RegorusEngine* E;
|
||||
public Engine()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
E = RegorusFFI.API.regorus_engine_new();
|
||||
}
|
||||
}
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
var clone = (Engine)this.MemberwiseClone();
|
||||
unsafe
|
||||
{
|
||||
clone.E = RegorusFFI.API.regorus_engine_clone(E);
|
||||
}
|
||||
return clone;
|
||||
|
||||
}
|
||||
|
||||
public void AddPolicy(string path, string rego)
|
||||
{
|
||||
var pathBytes = Encoding.UTF8.GetBytes(path);
|
||||
var regoBytes = Encoding.UTF8.GetBytes(rego);
|
||||
|
||||
unsafe
|
||||
{
|
||||
fixed (byte* pathPtr = pathBytes)
|
||||
{
|
||||
fixed(byte* regoPtr = regoBytes)
|
||||
{
|
||||
CheckAndDropResult(RegorusFFI.API.regorus_engine_add_policy(E, pathPtr, regoPtr));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AddPolicyFromFile(string path)
|
||||
{
|
||||
var pathBytes = Encoding.UTF8.GetBytes(path);
|
||||
|
||||
unsafe
|
||||
{
|
||||
fixed (byte* pathPtr = pathBytes)
|
||||
{
|
||||
CheckAndDropResult(RegorusFFI.API.regorus_engine_add_policy_from_file(E, pathPtr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AddDataJson(string data)
|
||||
{
|
||||
var dataBytes = Encoding.UTF8.GetBytes(data);
|
||||
|
||||
unsafe
|
||||
{
|
||||
fixed (byte* dataPtr = dataBytes)
|
||||
{
|
||||
CheckAndDropResult(RegorusFFI.API.regorus_engine_add_data_json(E, dataPtr));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AddDataFromJsonFile(string path)
|
||||
{
|
||||
var pathBytes = Encoding.UTF8.GetBytes(path);
|
||||
|
||||
unsafe
|
||||
{
|
||||
fixed (byte* pathPtr = pathBytes)
|
||||
{
|
||||
CheckAndDropResult(RegorusFFI.API.regorus_engine_add_data_from_json_file(E, pathPtr));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetInputJson(string input)
|
||||
{
|
||||
var inputBytes = Encoding.UTF8.GetBytes(input);
|
||||
|
||||
unsafe
|
||||
{
|
||||
fixed (byte* inputPtr = inputBytes)
|
||||
{
|
||||
CheckAndDropResult(RegorusFFI.API.regorus_engine_set_input_json(E, inputPtr));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetInputFromJsonFile(string path)
|
||||
{
|
||||
var pathBytes = Encoding.UTF8.GetBytes(path);
|
||||
|
||||
unsafe
|
||||
{
|
||||
fixed (byte* pathPtr = pathBytes)
|
||||
{
|
||||
CheckAndDropResult(RegorusFFI.API.regorus_engine_set_input_from_json_file(E, pathPtr));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string EvalQuery(string query)
|
||||
{
|
||||
var queryBytes = Encoding.UTF8.GetBytes(query);
|
||||
|
||||
var resultJson = "";
|
||||
unsafe
|
||||
{
|
||||
fixed (byte* queryPtr = queryBytes)
|
||||
{
|
||||
var result = RegorusFFI.API.regorus_engine_eval_query(E, queryPtr);
|
||||
if (result.status == RegorusFFI.RegorusStatus.RegorusStatusOk) {
|
||||
if (result.output is not null) {
|
||||
resultJson = System.Runtime.InteropServices.Marshal.PtrToStringUTF8((IntPtr)result.output);
|
||||
}
|
||||
RegorusFFI.API.regorus_result_drop(result);
|
||||
} else {
|
||||
CheckAndDropResult(result);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (resultJson is not null) {
|
||||
return resultJson;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
~Engine()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
RegorusFFI.API.regorus_engine_drop(E);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CheckAndDropResult(RegorusFFI.RegorusResult result)
|
||||
{
|
||||
if (result.status != RegorusFFI.RegorusStatus.RegorusStatusOk) {
|
||||
unsafe {
|
||||
var message = System.Runtime.InteropServices.Marshal.PtrToStringUTF8((IntPtr)result.error_message);
|
||||
var ex = new Exception(message);
|
||||
RegorusFFI.API.regorus_result_drop(result);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
RegorusFFI.API.regorus_result_drop(result);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
24
bindings/csharp/regorus-test.csproj
Normal file
24
bindings/csharp/regorus-test.csproj
Normal file
@@ -0,0 +1,24 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Target Name="BuildRegorusFFI">
|
||||
<Exec Command="cargo build -r --manifest-path ../ffi/Cargo.toml" />
|
||||
<Copy SourceFiles="../ffi/RegorusFFI.g.cs" DestinationFolder="." />
|
||||
<ItemGroup>
|
||||
<RegorusDylib Include="..\..\target\release\*regorus_ffi*" />
|
||||
</ItemGroup>
|
||||
<Copy SourceFiles="@(RegorusDylib)" DestinationFolder="." />
|
||||
</Target>
|
||||
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<RootNamespace>regorus_test</RootNamespace>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
|
||||
</Project>
|
||||
17
bindings/ffi/Cargo.toml
Normal file
17
bindings/ffi/Cargo.toml
Normal file
@@ -0,0 +1,17 @@
|
||||
[package]
|
||||
name = "regorus-ffi"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.79"
|
||||
regorus = { path = "../.." }
|
||||
serde_json = "1.0.113"
|
||||
|
||||
[build-dependencies]
|
||||
cbindgen = "0.26.0"
|
||||
csbindgen = "1.9.0"
|
||||
88
bindings/ffi/RegorusFFI.g.cs
Normal file
88
bindings/ffi/RegorusFFI.g.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
// <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 RegorusFFI
|
||||
{
|
||||
internal static unsafe partial class API
|
||||
{
|
||||
const string __DllName = "regorusc";
|
||||
|
||||
|
||||
|
||||
/// <summary>Drop a `RegorusResult`. `output` and `error_message` strings are not valid after drop.</summary>
|
||||
[DllImport(__DllName, EntryPoint = "regorus_result_drop", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern void regorus_result_drop(RegorusResult r);
|
||||
|
||||
/// <summary>Construct a new Engine See https://docs.rs/regorus/latest/regorus/struct.Engine.html</summary>
|
||||
[DllImport(__DllName, EntryPoint = "regorus_engine_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern RegorusEngine* regorus_engine_new();
|
||||
|
||||
/// <summary>Clone a [`RegorusEngine`] To avoid having to parse same policy again, the engine can be cloned after policies and data have been added.</summary>
|
||||
[DllImport(__DllName, EntryPoint = "regorus_engine_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern RegorusEngine* regorus_engine_clone(RegorusEngine* engine);
|
||||
|
||||
[DllImport(__DllName, EntryPoint = "regorus_engine_drop", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern void regorus_engine_drop(RegorusEngine* engine);
|
||||
|
||||
/// <summary>Add a policy The policy is parsed into AST. See https://docs.rs/regorus/latest/regorus/struct.Engine.html#method.add_policy * `path`: A filename to be associated with the policy. * `rego`: Rego policy.</summary>
|
||||
[DllImport(__DllName, EntryPoint = "regorus_engine_add_policy", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern RegorusResult regorus_engine_add_policy(RegorusEngine* engine, byte* path, byte* rego);
|
||||
|
||||
[DllImport(__DllName, EntryPoint = "regorus_engine_add_policy_from_file", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern RegorusResult regorus_engine_add_policy_from_file(RegorusEngine* engine, byte* path);
|
||||
|
||||
/// <summary>Add policy data. See https://docs.rs/regorus/latest/regorus/struct.Engine.html#method.add_data * `data`: JSON encoded value to be used as policy data.</summary>
|
||||
[DllImport(__DllName, EntryPoint = "regorus_engine_add_data_json", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern RegorusResult regorus_engine_add_data_json(RegorusEngine* engine, byte* data);
|
||||
|
||||
[DllImport(__DllName, EntryPoint = "regorus_engine_add_data_from_json_file", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern RegorusResult regorus_engine_add_data_from_json_file(RegorusEngine* engine, byte* path);
|
||||
|
||||
/// <summary>Clear policy data. See https://docs.rs/regorus/0.1.0-alpha.2/regorus/struct.Engine.html#method.clear_data</summary>
|
||||
[DllImport(__DllName, EntryPoint = "regorus_engine_clear_data", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern RegorusResult regorus_engine_clear_data(RegorusEngine* engine);
|
||||
|
||||
/// <summary>Set input. See https://docs.rs/regorus/0.1.0-alpha.2/regorus/struct.Engine.html#method.set_input * `input`: JSON encoded value to be used as input to query.</summary>
|
||||
[DllImport(__DllName, EntryPoint = "regorus_engine_set_input_json", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern RegorusResult regorus_engine_set_input_json(RegorusEngine* engine, byte* input);
|
||||
|
||||
[DllImport(__DllName, EntryPoint = "regorus_engine_set_input_from_json_file", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern RegorusResult regorus_engine_set_input_from_json_file(RegorusEngine* engine, byte* path);
|
||||
|
||||
/// <summary>Evaluate query. See https://docs.rs/regorus/0.1.0-alpha.2/regorus/struct.Engine.html#method.eval_query * `query`: Rego expression to be evaluate.</summary>
|
||||
[DllImport(__DllName, EntryPoint = "regorus_engine_eval_query", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern RegorusResult regorus_engine_eval_query(RegorusEngine* engine, byte* query);
|
||||
|
||||
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal unsafe partial struct RegorusResult
|
||||
{
|
||||
public RegorusStatus status;
|
||||
public byte* output;
|
||||
public byte* error_message;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal unsafe partial struct RegorusEngine
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
internal enum RegorusStatus : uint
|
||||
{
|
||||
RegorusStatusOk,
|
||||
RegorusStatusError,
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
32
bindings/ffi/build.rs
Normal file
32
bindings/ffi/build.rs
Normal file
@@ -0,0 +1,32 @@
|
||||
extern crate cbindgen;
|
||||
extern crate csbindgen;
|
||||
|
||||
use std::env;
|
||||
|
||||
fn main() {
|
||||
let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
|
||||
|
||||
cbindgen::Builder::new()
|
||||
.with_crate(&crate_dir)
|
||||
.with_language(cbindgen::Language::C)
|
||||
.with_include_guard("REGORUS_H")
|
||||
.generate()
|
||||
.expect("Unable to generate bindings")
|
||||
.write_to_file("regorus.h");
|
||||
|
||||
cbindgen::Builder::new()
|
||||
.with_crate(crate_dir)
|
||||
.with_language(cbindgen::Language::Cxx)
|
||||
.with_include_guard("REGORUS_HPP")
|
||||
.generate()
|
||||
.expect("Unable to generate bindings")
|
||||
.write_to_file("regorus.hpp");
|
||||
|
||||
csbindgen::Builder::default()
|
||||
.input_extern_file("src/lib.rs")
|
||||
.csharp_dll_name("regorusc")
|
||||
.csharp_class_name("API")
|
||||
.csharp_namespace("RegorusFFI")
|
||||
.generate_csharp_file("./RegorusFFI.g.cs")
|
||||
.unwrap();
|
||||
}
|
||||
158
bindings/ffi/cbindgen.toml
Normal file
158
bindings/ffi/cbindgen.toml
Normal file
@@ -0,0 +1,158 @@
|
||||
# This is a template cbindgen.toml file with all of the default values.
|
||||
# Some values are commented out because their absence is the real default.
|
||||
#
|
||||
# See https://github.com/mozilla/cbindgen/blob/master/docs.md#cbindgentoml
|
||||
# for detailed documentation of every option here.
|
||||
|
||||
|
||||
|
||||
language = "C++"
|
||||
|
||||
|
||||
|
||||
############## Options for Wrapping the Contents of the Header #################
|
||||
|
||||
# header = "/* Text to put at the beginning of the generated file. Probably a license. */"
|
||||
# trailer = "/* Text to put at the end of the generated file */"
|
||||
# include_guard = "my_bindings_h"
|
||||
# pragma_once = true
|
||||
# autogen_warning = "/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */"
|
||||
include_version = false
|
||||
# namespace = "my_namespace"
|
||||
namespaces = []
|
||||
using_namespaces = []
|
||||
sys_includes = []
|
||||
includes = []
|
||||
no_includes = false
|
||||
after_includes = ""
|
||||
|
||||
|
||||
|
||||
|
||||
############################ Code Style Options ################################
|
||||
|
||||
braces = "SameLine"
|
||||
line_length = 100
|
||||
tab_width = 2
|
||||
documentation = true
|
||||
documentation_style = "auto"
|
||||
documentation_length = "full"
|
||||
line_endings = "LF" # also "CR", "CRLF", "Native"
|
||||
|
||||
|
||||
|
||||
|
||||
############################# Codegen Options ##################################
|
||||
|
||||
style = "both"
|
||||
sort_by = "Name" # default for `fn.sort_by` and `const.sort_by`
|
||||
usize_is_size_t = true
|
||||
|
||||
|
||||
|
||||
[defines]
|
||||
# "target_os = freebsd" = "DEFINE_FREEBSD"
|
||||
# "feature = serde" = "DEFINE_SERDE"
|
||||
|
||||
|
||||
|
||||
[export]
|
||||
include = []
|
||||
exclude = []
|
||||
# prefix = "CAPI_"
|
||||
item_types = []
|
||||
renaming_overrides_prefixing = false
|
||||
|
||||
|
||||
|
||||
[export.rename]
|
||||
|
||||
|
||||
|
||||
[export.body]
|
||||
|
||||
|
||||
[export.mangle]
|
||||
|
||||
|
||||
[fn]
|
||||
rename_args = "None"
|
||||
# must_use = "MUST_USE_FUNC"
|
||||
# deprecated = "DEPRECATED_FUNC"
|
||||
# deprecated_with_note = "DEPRECATED_FUNC_WITH_NOTE"
|
||||
# no_return = "NO_RETURN"
|
||||
# prefix = "START_FUNC"
|
||||
# postfix = "END_FUNC"
|
||||
args = "auto"
|
||||
sort_by = "Name"
|
||||
|
||||
|
||||
|
||||
|
||||
[struct]
|
||||
rename_fields = "None"
|
||||
# must_use = "MUST_USE_STRUCT"
|
||||
# deprecated = "DEPRECATED_STRUCT"
|
||||
# deprecated_with_note = "DEPRECATED_STRUCT_WITH_NOTE"
|
||||
derive_constructor = false
|
||||
derive_eq = false
|
||||
derive_neq = false
|
||||
derive_lt = false
|
||||
derive_lte = false
|
||||
derive_gt = false
|
||||
derive_gte = false
|
||||
|
||||
|
||||
|
||||
|
||||
[enum]
|
||||
rename_variants = "None"
|
||||
# must_use = "MUST_USE_ENUM"
|
||||
# deprecated = "DEPRECATED_ENUM"
|
||||
# deprecated_with_note = "DEPRECATED_ENUM_WITH_NOTE"
|
||||
add_sentinel = false
|
||||
prefix_with_name = false
|
||||
derive_helper_methods = false
|
||||
derive_const_casts = false
|
||||
derive_mut_casts = false
|
||||
# cast_assert_name = "ASSERT"
|
||||
derive_tagged_enum_destructor = false
|
||||
derive_tagged_enum_copy_constructor = false
|
||||
enum_class = true
|
||||
private_default_tagged_enum_constructor = false
|
||||
|
||||
|
||||
|
||||
|
||||
[const]
|
||||
allow_static_const = true
|
||||
allow_constexpr = false
|
||||
sort_by = "Name"
|
||||
|
||||
|
||||
|
||||
|
||||
[macro_expansion]
|
||||
bitflags = false
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
############## Options for How Your Rust library Should Be Parsed ##############
|
||||
|
||||
[parse]
|
||||
parse_deps = false
|
||||
# include = []
|
||||
exclude = []
|
||||
clean = false
|
||||
extra_bindings = []
|
||||
|
||||
|
||||
|
||||
[parse.expand]
|
||||
crates = []
|
||||
all_features = false
|
||||
default_features = true
|
||||
features = []
|
||||
127
bindings/ffi/regorus.h
Normal file
127
bindings/ffi/regorus.h
Normal file
@@ -0,0 +1,127 @@
|
||||
#ifndef REGORUS_H
|
||||
#define REGORUS_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* Status of a call on `RegorusEngine`.
|
||||
*/
|
||||
typedef enum RegorusStatus {
|
||||
/**
|
||||
* The operation was successful.
|
||||
*/
|
||||
RegorusStatusOk,
|
||||
/**
|
||||
* The operation was unsuccessful.
|
||||
*/
|
||||
RegorusStatusError,
|
||||
} RegorusStatus;
|
||||
|
||||
/**
|
||||
* Wrapper for `regorus::Engine`.
|
||||
*/
|
||||
typedef struct RegorusEngine RegorusEngine;
|
||||
|
||||
/**
|
||||
* Result of a call on `RegorusEngine`.
|
||||
*
|
||||
* Must be freed using `regorus_result_drop`.
|
||||
*/
|
||||
typedef struct RegorusResult {
|
||||
/**
|
||||
* Status
|
||||
*/
|
||||
enum RegorusStatus status;
|
||||
/**
|
||||
* Output produced by the call.
|
||||
* Owned by Rust.
|
||||
*/
|
||||
char *output;
|
||||
/**
|
||||
* Errors produced by the call.
|
||||
* Owned by Rust.
|
||||
*/
|
||||
char *error_message;
|
||||
} RegorusResult;
|
||||
|
||||
/**
|
||||
* Drop a `RegorusResult`.
|
||||
*
|
||||
* `output` and `error_message` strings are not valid after drop.
|
||||
*/
|
||||
void regorus_result_drop(struct RegorusResult r);
|
||||
|
||||
/**
|
||||
* Construct a new Engine
|
||||
*
|
||||
* See https://docs.rs/regorus/latest/regorus/struct.Engine.html
|
||||
*/
|
||||
struct RegorusEngine *regorus_engine_new(void);
|
||||
|
||||
/**
|
||||
* Clone a [`RegorusEngine`]
|
||||
*
|
||||
* To avoid having to parse same policy again, the engine can be cloned
|
||||
* after policies and data have been added.
|
||||
*/
|
||||
struct RegorusEngine *regorus_engine_clone(struct RegorusEngine *engine);
|
||||
|
||||
void regorus_engine_drop(struct RegorusEngine *engine);
|
||||
|
||||
/**
|
||||
* Add a policy
|
||||
*
|
||||
* The policy is parsed into AST.
|
||||
* See https://docs.rs/regorus/latest/regorus/struct.Engine.html#method.add_policy
|
||||
*
|
||||
* * `path`: A filename to be associated with the policy.
|
||||
* * `rego`: Rego policy.
|
||||
*/
|
||||
struct RegorusResult regorus_engine_add_policy(struct RegorusEngine *engine,
|
||||
const char *path,
|
||||
const char *rego);
|
||||
|
||||
struct RegorusResult regorus_engine_add_policy_from_file(struct RegorusEngine *engine,
|
||||
const char *path);
|
||||
|
||||
/**
|
||||
* Add policy data.
|
||||
*
|
||||
* See https://docs.rs/regorus/latest/regorus/struct.Engine.html#method.add_data
|
||||
* * `data`: JSON encoded value to be used as policy data.
|
||||
*/
|
||||
struct RegorusResult regorus_engine_add_data_json(struct RegorusEngine *engine, const char *data);
|
||||
|
||||
struct RegorusResult regorus_engine_add_data_from_json_file(struct RegorusEngine *engine,
|
||||
const char *path);
|
||||
|
||||
/**
|
||||
* Clear policy data.
|
||||
*
|
||||
* See https://docs.rs/regorus/0.1.0-alpha.2/regorus/struct.Engine.html#method.clear_data
|
||||
*/
|
||||
struct RegorusResult regorus_engine_clear_data(struct RegorusEngine *engine);
|
||||
|
||||
/**
|
||||
* Set input.
|
||||
*
|
||||
* See https://docs.rs/regorus/0.1.0-alpha.2/regorus/struct.Engine.html#method.set_input
|
||||
* * `input`: JSON encoded value to be used as input to query.
|
||||
*/
|
||||
struct RegorusResult regorus_engine_set_input_json(struct RegorusEngine *engine, const char *input);
|
||||
|
||||
struct RegorusResult regorus_engine_set_input_from_json_file(struct RegorusEngine *engine,
|
||||
const char *path);
|
||||
|
||||
/**
|
||||
* Evaluate query.
|
||||
*
|
||||
* See https://docs.rs/regorus/0.1.0-alpha.2/regorus/struct.Engine.html#method.eval_query
|
||||
* * `query`: Rego expression to be evaluate.
|
||||
*/
|
||||
struct RegorusResult regorus_engine_eval_query(struct RegorusEngine *engine, const char *query);
|
||||
|
||||
#endif /* REGORUS_H */
|
||||
95
bindings/ffi/regorus.hpp
Normal file
95
bindings/ffi/regorus.hpp
Normal file
@@ -0,0 +1,95 @@
|
||||
#ifndef REGORUS_HPP
|
||||
#define REGORUS_HPP
|
||||
|
||||
#include <cstdarg>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <ostream>
|
||||
#include <new>
|
||||
|
||||
/// Status of a call on `RegorusEngine`.
|
||||
enum class RegorusStatus {
|
||||
/// The operation was successful.
|
||||
RegorusStatusOk,
|
||||
/// The operation was unsuccessful.
|
||||
RegorusStatusError,
|
||||
};
|
||||
|
||||
/// Wrapper for `regorus::Engine`.
|
||||
struct RegorusEngine;
|
||||
|
||||
/// Result of a call on `RegorusEngine`.
|
||||
///
|
||||
/// Must be freed using `regorus_result_drop`.
|
||||
struct RegorusResult {
|
||||
/// Status
|
||||
RegorusStatus status;
|
||||
/// Output produced by the call.
|
||||
/// Owned by Rust.
|
||||
char *output;
|
||||
/// Errors produced by the call.
|
||||
/// Owned by Rust.
|
||||
char *error_message;
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
|
||||
/// Drop a `RegorusResult`.
|
||||
///
|
||||
/// `output` and `error_message` strings are not valid after drop.
|
||||
void regorus_result_drop(RegorusResult r);
|
||||
|
||||
/// Construct a new Engine
|
||||
///
|
||||
/// See https://docs.rs/regorus/latest/regorus/struct.Engine.html
|
||||
RegorusEngine *regorus_engine_new();
|
||||
|
||||
/// Clone a [`RegorusEngine`]
|
||||
///
|
||||
/// To avoid having to parse same policy again, the engine can be cloned
|
||||
/// after policies and data have been added.
|
||||
RegorusEngine *regorus_engine_clone(RegorusEngine *engine);
|
||||
|
||||
void regorus_engine_drop(RegorusEngine *engine);
|
||||
|
||||
/// Add a policy
|
||||
///
|
||||
/// The policy is parsed into AST.
|
||||
/// See https://docs.rs/regorus/latest/regorus/struct.Engine.html#method.add_policy
|
||||
///
|
||||
/// * `path`: A filename to be associated with the policy.
|
||||
/// * `rego`: Rego policy.
|
||||
RegorusResult regorus_engine_add_policy(RegorusEngine *engine, const char *path, const char *rego);
|
||||
|
||||
RegorusResult regorus_engine_add_policy_from_file(RegorusEngine *engine, const char *path);
|
||||
|
||||
/// Add policy data.
|
||||
///
|
||||
/// See https://docs.rs/regorus/latest/regorus/struct.Engine.html#method.add_data
|
||||
/// * `data`: JSON encoded value to be used as policy data.
|
||||
RegorusResult regorus_engine_add_data_json(RegorusEngine *engine, const char *data);
|
||||
|
||||
RegorusResult regorus_engine_add_data_from_json_file(RegorusEngine *engine, const char *path);
|
||||
|
||||
/// Clear policy data.
|
||||
///
|
||||
/// See https://docs.rs/regorus/0.1.0-alpha.2/regorus/struct.Engine.html#method.clear_data
|
||||
RegorusResult regorus_engine_clear_data(RegorusEngine *engine);
|
||||
|
||||
/// Set input.
|
||||
///
|
||||
/// See https://docs.rs/regorus/0.1.0-alpha.2/regorus/struct.Engine.html#method.set_input
|
||||
/// * `input`: JSON encoded value to be used as input to query.
|
||||
RegorusResult regorus_engine_set_input_json(RegorusEngine *engine, const char *input);
|
||||
|
||||
RegorusResult regorus_engine_set_input_from_json_file(RegorusEngine *engine, const char *path);
|
||||
|
||||
/// Evaluate query.
|
||||
///
|
||||
/// See https://docs.rs/regorus/0.1.0-alpha.2/regorus/struct.Engine.html#method.eval_query
|
||||
/// * `query`: Rego expression to be evaluate.
|
||||
RegorusResult regorus_engine_eval_query(RegorusEngine *engine, const char *query);
|
||||
|
||||
} // extern "C"
|
||||
|
||||
#endif // REGORUS_HPP
|
||||
248
bindings/ffi/src/lib.rs
Normal file
248
bindings/ffi/src/lib.rs
Normal file
@@ -0,0 +1,248 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
use anyhow::{anyhow, bail, Result};
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::os::raw::c_char;
|
||||
|
||||
/// Status of a call on `RegorusEngine`.
|
||||
#[repr(C)]
|
||||
pub enum RegorusStatus {
|
||||
/// The operation was successful.
|
||||
RegorusStatusOk,
|
||||
|
||||
/// The operation was unsuccessful.
|
||||
RegorusStatusError,
|
||||
}
|
||||
|
||||
/// Result of a call on `RegorusEngine`.
|
||||
///
|
||||
/// Must be freed using `regorus_result_drop`.
|
||||
#[repr(C)]
|
||||
pub struct RegorusResult {
|
||||
/// Status
|
||||
status: RegorusStatus,
|
||||
|
||||
/// Output produced by the call.
|
||||
/// Owned by Rust.
|
||||
output: *mut c_char,
|
||||
|
||||
/// Errors produced by the call.
|
||||
/// Owned by Rust.
|
||||
error_message: *mut c_char,
|
||||
}
|
||||
|
||||
fn to_c_str(s: String) -> *mut c_char {
|
||||
match CString::new(s) {
|
||||
Ok(cs) => cs.into_raw(),
|
||||
_ => to_c_str("binding error: failed to create c-style string".to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
fn from_c_str(s: *const c_char) -> Result<String> {
|
||||
if s.is_null() {
|
||||
bail!("null pointer");
|
||||
}
|
||||
unsafe {
|
||||
CStr::from_ptr(s)
|
||||
.to_str()
|
||||
.map_err(|_| anyhow!("`path`: invalid utf8"))
|
||||
.map(|s| s.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
fn to_ref<T>(t: &*mut T) -> Result<&mut T> {
|
||||
unsafe { t.as_mut().ok_or_else(|| anyhow!("null pointer")) }
|
||||
}
|
||||
|
||||
fn to_regorus_result(r: Result<()>) -> RegorusResult {
|
||||
match r {
|
||||
Ok(()) => RegorusResult {
|
||||
status: RegorusStatus::RegorusStatusOk,
|
||||
output: std::ptr::null_mut(),
|
||||
error_message: std::ptr::null_mut(),
|
||||
},
|
||||
Err(e) => RegorusResult {
|
||||
status: RegorusStatus::RegorusStatusError,
|
||||
output: std::ptr::null_mut(),
|
||||
error_message: to_c_str(format!("{e}")),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Wrapper for `regorus::Engine`.
|
||||
#[derive(Clone)]
|
||||
pub struct RegorusEngine {
|
||||
engine: ::regorus::Engine,
|
||||
}
|
||||
|
||||
/// Drop a `RegorusResult`.
|
||||
///
|
||||
/// `output` and `error_message` strings are not valid after drop.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn regorus_result_drop(r: RegorusResult) {
|
||||
if !r.error_message.is_null() {
|
||||
unsafe {
|
||||
let _ = CString::from_raw(r.error_message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
/// Construct a new Engine
|
||||
///
|
||||
/// See https://docs.rs/regorus/latest/regorus/struct.Engine.html
|
||||
pub extern "C" fn regorus_engine_new() -> *mut RegorusEngine {
|
||||
let engine = ::regorus::Engine::new();
|
||||
Box::into_raw(Box::new(RegorusEngine { engine }))
|
||||
}
|
||||
|
||||
/// Clone a [`RegorusEngine`]
|
||||
///
|
||||
/// To avoid having to parse same policy again, the engine can be cloned
|
||||
/// after policies and data have been added.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn regorus_engine_clone(engine: *mut RegorusEngine) -> *mut RegorusEngine {
|
||||
unsafe {
|
||||
if engine.is_null() {
|
||||
return std::ptr::null_mut();
|
||||
}
|
||||
Box::into_raw(Box::new((*engine).clone()))
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn regorus_engine_drop(engine: *mut RegorusEngine) {
|
||||
if !engine.is_null() {
|
||||
unsafe {
|
||||
let _ = Box::from_raw(engine);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Add a policy
|
||||
///
|
||||
/// The policy is parsed into AST.
|
||||
/// See https://docs.rs/regorus/latest/regorus/struct.Engine.html#method.add_policy
|
||||
///
|
||||
/// * `path`: A filename to be associated with the policy.
|
||||
/// * `rego`: Rego policy.
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn regorus_engine_add_policy(
|
||||
engine: *mut RegorusEngine,
|
||||
path: *const c_char,
|
||||
rego: *const c_char,
|
||||
) -> RegorusResult {
|
||||
to_regorus_result(|| -> Result<()> {
|
||||
to_ref(&engine)?
|
||||
.engine
|
||||
.add_policy(from_c_str(path)?, from_c_str(rego)?)
|
||||
}())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn regorus_engine_add_policy_from_file(
|
||||
engine: *mut RegorusEngine,
|
||||
path: *const c_char,
|
||||
) -> RegorusResult {
|
||||
to_regorus_result(|| -> Result<()> {
|
||||
to_ref(&engine)?
|
||||
.engine
|
||||
.add_policy_from_file(from_c_str(path)?)
|
||||
}())
|
||||
}
|
||||
|
||||
/// Add policy data.
|
||||
///
|
||||
/// See https://docs.rs/regorus/latest/regorus/struct.Engine.html#method.add_data
|
||||
/// * `data`: JSON encoded value to be used as policy data.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn regorus_engine_add_data_json(
|
||||
engine: *mut RegorusEngine,
|
||||
data: *const c_char,
|
||||
) -> RegorusResult {
|
||||
to_regorus_result(|| -> Result<()> {
|
||||
to_ref(&engine)?
|
||||
.engine
|
||||
.add_data(regorus::Value::from_json_str(&from_c_str(data)?)?)
|
||||
}())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn regorus_engine_add_data_from_json_file(
|
||||
engine: *mut RegorusEngine,
|
||||
path: *const c_char,
|
||||
) -> RegorusResult {
|
||||
to_regorus_result(|| -> Result<()> {
|
||||
to_ref(&engine)?
|
||||
.engine
|
||||
.add_data(regorus::Value::from_json_file(&from_c_str(path)?)?)
|
||||
}())
|
||||
}
|
||||
|
||||
/// Clear policy data.
|
||||
///
|
||||
/// See https://docs.rs/regorus/0.1.0-alpha.2/regorus/struct.Engine.html#method.clear_data
|
||||
#[no_mangle]
|
||||
pub extern "C" fn regorus_engine_clear_data(engine: *mut RegorusEngine) -> RegorusResult {
|
||||
to_regorus_result(|| -> Result<()> {
|
||||
to_ref(&engine)?.engine.clear_data();
|
||||
Ok(())
|
||||
}())
|
||||
}
|
||||
|
||||
/// Set input.
|
||||
///
|
||||
/// See https://docs.rs/regorus/0.1.0-alpha.2/regorus/struct.Engine.html#method.set_input
|
||||
/// * `input`: JSON encoded value to be used as input to query.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn regorus_engine_set_input_json(
|
||||
engine: *mut RegorusEngine,
|
||||
input: *const c_char,
|
||||
) -> RegorusResult {
|
||||
to_regorus_result(|| -> Result<()> {
|
||||
to_ref(&engine)?
|
||||
.engine
|
||||
.set_input(regorus::Value::from_json_str(&from_c_str(input)?)?);
|
||||
Ok(())
|
||||
}())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn regorus_engine_set_input_from_json_file(
|
||||
engine: *mut RegorusEngine,
|
||||
path: *const c_char,
|
||||
) -> RegorusResult {
|
||||
to_regorus_result(|| -> Result<()> {
|
||||
to_ref(&engine)?
|
||||
.engine
|
||||
.set_input(regorus::Value::from_json_file(&from_c_str(path)?)?);
|
||||
Ok(())
|
||||
}())
|
||||
}
|
||||
|
||||
/// Evaluate query.
|
||||
///
|
||||
/// See https://docs.rs/regorus/0.1.0-alpha.2/regorus/struct.Engine.html#method.eval_query
|
||||
/// * `query`: Rego expression to be evaluate.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn regorus_engine_eval_query(
|
||||
engine: *mut RegorusEngine,
|
||||
query: *const c_char,
|
||||
) -> RegorusResult {
|
||||
let output = || -> Result<String> {
|
||||
let results = to_ref(&engine)?
|
||||
.engine
|
||||
.eval_query(from_c_str(query)?, false)?;
|
||||
Ok(serde_json::to_string_pretty(&results)?)
|
||||
}();
|
||||
match output {
|
||||
Ok(out) => RegorusResult {
|
||||
status: RegorusStatus::RegorusStatusOk,
|
||||
output: to_c_str(out),
|
||||
error_message: std::ptr::null_mut(),
|
||||
},
|
||||
Err(e) => to_regorus_result(Err(e)),
|
||||
}
|
||||
}
|
||||
3
bindings/go/go.mod
Normal file
3
bindings/go/go.mod
Normal file
@@ -0,0 +1,3 @@
|
||||
module regorus-test
|
||||
|
||||
go 1.21.5
|
||||
58
bindings/go/main.go
Normal file
58
bindings/go/main.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"regorus-test/pkg/regorus"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var output string
|
||||
var err error
|
||||
|
||||
t := time.Now();
|
||||
|
||||
// Create new engine
|
||||
engine := regorus.NewEngine()
|
||||
defer engine.Close()
|
||||
elapsed1 := time.Since(t)
|
||||
|
||||
t = time.Now()
|
||||
// Add policies and data.
|
||||
policies := []string{
|
||||
"../../tests/aci/framework.rego",
|
||||
"../../tests/aci/api.rego",
|
||||
"../../tests/aci/policy.rego",
|
||||
}
|
||||
for _, policy := range policies {
|
||||
if err := engine.AddPolicyFromFile(policy); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
if err = engine.AddDataFromJsonFile("../../tests/aci/data.json"); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
elapsed2 := time.Since(t)
|
||||
|
||||
t = time.Now()
|
||||
// Set input and eval query.
|
||||
if err = engine.SetInputFromJsonFile("../../tests/aci/input.json"); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
|
||||
if output, err = engine.EvalQuery("data.framework.mount_overlay = x"); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
elapsed3 := time.Since(t)
|
||||
|
||||
fmt.Println("{%s}", output)
|
||||
fmt.Printf("NewEngine took %v\n", elapsed1)
|
||||
fmt.Printf("Add policies and data took %v\n", elapsed2)
|
||||
fmt.Printf("Set input and eval query took %v\n", elapsed3)
|
||||
}
|
||||
117
bindings/go/pkg/regorus/mod.go
Normal file
117
bindings/go/pkg/regorus/mod.go
Normal file
@@ -0,0 +1,117 @@
|
||||
package regorus
|
||||
|
||||
// #cgo LDFLAGS: -L ../../../../target/release -lregorus_ffi
|
||||
// #include "../../../ffi/regorus.h"
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type Engine struct {
|
||||
e *C.RegorusEngine
|
||||
}
|
||||
|
||||
func NewEngine() *Engine {
|
||||
e := new(Engine)
|
||||
e.e = C.regorus_engine_new()
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *Engine) Close() {
|
||||
C.regorus_engine_drop(e.e)
|
||||
}
|
||||
|
||||
func (e *Engine) Clone() *Engine {
|
||||
c := new(Engine)
|
||||
c.e = C.regorus_engine_clone(e.e)
|
||||
return c
|
||||
}
|
||||
|
||||
func (e *Engine) AddPolicy(path string, rego string) error {
|
||||
path_c := C.CString(path)
|
||||
defer C.free(unsafe.Pointer(path_c))
|
||||
|
||||
rego_c := C.CString(rego)
|
||||
defer C.free(unsafe.Pointer(rego_c))
|
||||
|
||||
result := C.regorus_engine_add_policy(e.e, path_c, rego_c)
|
||||
defer C.regorus_result_drop(result)
|
||||
if result.status != C.RegorusStatusOk {
|
||||
return fmt.Errorf("%s", C.GoString(result.error_message))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *Engine) AddPolicyFromFile(path string) error {
|
||||
path_c := C.CString(path)
|
||||
defer C.free(unsafe.Pointer(path_c))
|
||||
|
||||
result := C.regorus_engine_add_policy_from_file(e.e, path_c)
|
||||
defer C.regorus_result_drop(result)
|
||||
if result.status != C.RegorusStatusOk {
|
||||
return fmt.Errorf("%s", C.GoString(result.error_message))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *Engine) AddDataJson(data string) error {
|
||||
data_c := C.CString(data)
|
||||
defer C.free(unsafe.Pointer(data_c))
|
||||
|
||||
result := C.regorus_engine_add_data_json(e.e, data_c)
|
||||
defer C.regorus_result_drop(result)
|
||||
if result.status != C.RegorusStatusOk {
|
||||
return fmt.Errorf("%s", C.GoString(result.error_message))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *Engine) AddDataFromJsonFile(path string) error {
|
||||
path_c := C.CString(path)
|
||||
defer C.free(unsafe.Pointer(path_c))
|
||||
|
||||
result := C.regorus_engine_add_data_from_json_file(e.e, path_c)
|
||||
defer C.regorus_result_drop(result)
|
||||
if result.status != C.RegorusStatusOk {
|
||||
return fmt.Errorf("%s", C.GoString(result.error_message))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *Engine) SetInputJson(input string) error {
|
||||
input_c := C.CString(input)
|
||||
defer C.free(unsafe.Pointer(input_c))
|
||||
|
||||
result := C.regorus_engine_set_input_json(e.e, input_c)
|
||||
defer C.regorus_result_drop(result)
|
||||
if result.status != C.RegorusStatusOk {
|
||||
return fmt.Errorf("%s", C.GoString(result.error_message))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *Engine) SetInputFromJsonFile(path string) error {
|
||||
path_c := C.CString(path)
|
||||
defer C.free(unsafe.Pointer(path_c))
|
||||
|
||||
result := C.regorus_engine_set_input_from_json_file(e.e, path_c)
|
||||
defer C.regorus_result_drop(result)
|
||||
if result.status != C.RegorusStatusOk {
|
||||
return fmt.Errorf("%s", C.GoString(result.error_message))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *Engine) EvalQuery(query string) (string, error) {
|
||||
query_c := C.CString(query)
|
||||
defer C.free(unsafe.Pointer(query_c))
|
||||
|
||||
result := C.regorus_engine_eval_query(e.e, query_c)
|
||||
defer C.regorus_result_drop(result)
|
||||
if result.status != C.RegorusStatusOk {
|
||||
return "", fmt.Errorf("%s", C.GoString(result.error_message))
|
||||
}
|
||||
|
||||
return C.GoString(result.output), nil
|
||||
}
|
||||
@@ -64,6 +64,8 @@ impl Engine {
|
||||
}
|
||||
|
||||
/// Clear policy data.
|
||||
///
|
||||
/// See https://docs.rs/regorus/0.1.0-alpha.2/regorus/struct.Engine.html#method.clear_data
|
||||
pub fn clear_data(&mut self) -> Result<(), JsValue> {
|
||||
self.engine.clear_data();
|
||||
Ok(())
|
||||
|
||||
Reference in New Issue
Block a user