mirror of
https://github.com/microsoft/regorus.git
synced 2026-08-05 02:16:11 +00:00
feat: Complete target system with C# bindings and resource inference (#458)
* feat: Add Schema Registry and Validation Framework This commit introduces a comprehensive schema registry and validation framework, providing schema-based validation of resources and policy effects. - Thread-safe, in-memory registry for schema storage and management - Global registry patterns for effects and resources - Concurrent access with proper error handling - Unicode schema names support - JSON Schema-compliant validation for all primitive types - Advanced constraint validation (patterns, ranges, length limits) - Discriminated union support with anyOf schemas - Detailed error reporting with nested validation paths - Discriminated subobject validation for polymorphic schemas - **Registry Tests**: All registry operations - **Effect Tests**: Policy effect validation - **Resource Tests**: Resource validation - **Validation Tests**: Core validation engine - Thread-safety, error handling, integration scenarios, edge cases - **Dependencies**: dashmap, once_cell, regex - **Thread Safety**: Minimal locking with Rc<Schema> sharing - **Error Types**: TypeMismatch, OutOfRange, PatternMismatch, etc. - Complete schema registry and validation subsystem - Comprehensive test coverage - Foundation for policy validation in Regorus Benchmarks: - Criterion benchmarks for basic types, effects and Azure resources - Performance range: 3.22ns (string) to 34.74µs (Azure VM resource schema validation) - String withs patterns validation: 30.2µs. Need to explore whether regex caching helps bring this down. - Azure policy effects: 188ns-1.4µs Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com> * feat: Complete target system with C# bindings and resource inference - Add comprehensive target system with TargetRegistry and target-aware compilation - Implement resource type inference from policy equality expressions - Create modular C# bindings with separate wrapper classes for each concept - Add thread-safe CompiledPolicy with reference counting for safe disposal - Enhance FFI with detailed error propagation and target functionality - Create TargetExampleApp demonstrating Azure Policy integration - Add CI/CD pipeline testing for all C# applications - Support target definitions with schema validation and resource selectors - Implement PolicyModule struct and target-aware compilation methods - Add comprehensive test coverage for target functionality 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
3c33d31d08
commit
cc917ea75d
+8
-550
@@ -1,553 +1,11 @@
|
||||
// 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(name: &str, s: *const c_char) -> Result<String> {
|
||||
if s.is_null() {
|
||||
bail!("null pointer");
|
||||
}
|
||||
unsafe {
|
||||
CStr::from_ptr(s)
|
||||
.to_str()
|
||||
.map_err(|e| anyhow!("`{name}`: invalid utf8.\n{e}"))
|
||||
.map(|s| s.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
fn to_ref<'a, T>(t: *mut T) -> Result<&'a 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}")),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn to_regorus_string_result(r: Result<String>) -> RegorusResult {
|
||||
match r {
|
||||
Ok(s) => RegorusResult {
|
||||
status: RegorusStatus::RegorusStatusOk,
|
||||
output: to_c_str(s),
|
||||
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) {
|
||||
unsafe {
|
||||
if !r.error_message.is_null() {
|
||||
let _ = CString::from_raw(r.error_message);
|
||||
}
|
||||
if !r.output.is_null() {
|
||||
let _ = CString::from_raw(r.output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[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 mut engine = ::regorus::Engine::new();
|
||||
|
||||
// For more OPA compatibility out of the box, we ask builtins to return undefined
|
||||
// instead of raising errors in certain failure scenarios.
|
||||
engine.set_strict_builtin_errors(false);
|
||||
|
||||
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 {
|
||||
match to_ref(engine) {
|
||||
Ok(e) => Box::into_raw(Box::new(e.clone())),
|
||||
_ => std::ptr::null_mut(),
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn regorus_engine_drop(engine: *mut RegorusEngine) {
|
||||
if let Ok(e) = to_ref(engine) {
|
||||
unsafe {
|
||||
let _ = Box::from_raw(std::ptr::from_mut(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 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_string_result(|| -> Result<String> {
|
||||
to_ref(engine)?
|
||||
.engine
|
||||
.add_policy(from_c_str("path", path)?, from_c_str("rego", rego)?)
|
||||
}())
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn regorus_engine_add_policy_from_file(
|
||||
engine: *mut RegorusEngine,
|
||||
path: *const c_char,
|
||||
) -> RegorusResult {
|
||||
to_regorus_string_result(|| -> Result<String> {
|
||||
to_ref(engine)?
|
||||
.engine
|
||||
.add_policy_from_file(from_c_str("path", 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", data)?)?)
|
||||
}())
|
||||
}
|
||||
|
||||
/// Get list of loaded Rego packages as JSON.
|
||||
///
|
||||
/// See https://docs.rs/regorus/latest/regorus/struct.Engine.html#method.get_packages
|
||||
#[no_mangle]
|
||||
pub extern "C" fn regorus_engine_get_packages(engine: *mut RegorusEngine) -> RegorusResult {
|
||||
to_regorus_string_result(|| -> Result<String> {
|
||||
serde_json::to_string_pretty(&to_ref(engine)?.engine.get_packages()?)
|
||||
.map_err(anyhow::Error::msg)
|
||||
}())
|
||||
}
|
||||
|
||||
/// Get list of policies as JSON.
|
||||
///
|
||||
/// See https://docs.rs/regorus/latest/regorus/struct.Engine.html#method.get_policies
|
||||
#[no_mangle]
|
||||
pub extern "C" fn regorus_engine_get_policies(engine: *mut RegorusEngine) -> RegorusResult {
|
||||
to_regorus_string_result(|| -> Result<String> {
|
||||
to_ref(engine)?.engine.get_policies_as_json()
|
||||
}())
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[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", path)?)?)
|
||||
}())
|
||||
}
|
||||
|
||||
/// Clear policy data.
|
||||
///
|
||||
/// See https://docs.rs/regorus/latest/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/latest/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", input)?)?);
|
||||
Ok(())
|
||||
}())
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[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", path)?)?);
|
||||
Ok(())
|
||||
}())
|
||||
}
|
||||
|
||||
/// Evaluate query.
|
||||
///
|
||||
/// See https://docs.rs/regorus/latest/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", 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)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Evaluate specified rule.
|
||||
///
|
||||
/// See https://docs.rs/regorus/latest/regorus/struct.Engine.html#method.eval_rule
|
||||
/// * `rule`: Path to the rule.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn regorus_engine_eval_rule(
|
||||
engine: *mut RegorusEngine,
|
||||
rule: *const c_char,
|
||||
) -> RegorusResult {
|
||||
let output = || -> Result<String> {
|
||||
to_ref(engine)?
|
||||
.engine
|
||||
.eval_rule(from_c_str("rule", rule)?)?
|
||||
.to_json_str()
|
||||
}();
|
||||
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)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Enable/disable coverage.
|
||||
///
|
||||
/// See https://docs.rs/regorus/latest/regorus/struct.Engine.html#method.set_enable_coverage
|
||||
/// * `enable`: Whether to enable or disable coverage.
|
||||
#[no_mangle]
|
||||
#[cfg(feature = "coverage")]
|
||||
pub extern "C" fn regorus_engine_set_enable_coverage(
|
||||
engine: *mut RegorusEngine,
|
||||
enable: bool,
|
||||
) -> RegorusResult {
|
||||
to_regorus_result(|| -> Result<()> {
|
||||
to_ref(engine)?.engine.set_enable_coverage(enable);
|
||||
Ok(())
|
||||
}())
|
||||
}
|
||||
|
||||
/// Get coverage report.
|
||||
///
|
||||
/// See https://docs.rs/regorus/latest/regorus/struct.Engine.html#method.get_coverage_report
|
||||
#[no_mangle]
|
||||
#[cfg(feature = "coverage")]
|
||||
pub extern "C" fn regorus_engine_get_coverage_report(engine: *mut RegorusEngine) -> RegorusResult {
|
||||
let output = || -> Result<String> {
|
||||
Ok(serde_json::to_string_pretty(
|
||||
&to_ref(engine)?.engine.get_coverage_report()?,
|
||||
)?)
|
||||
}();
|
||||
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)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Enable/disable strict builtin errors.
|
||||
///
|
||||
/// See https://docs.rs/regorus/latest/regorus/struct.Engine.html#method.set_strict_builtin_errors
|
||||
/// * `strict`: Whether to raise errors or return undefined on certain scenarios.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn regorus_engine_set_strict_builtin_errors(
|
||||
engine: *mut RegorusEngine,
|
||||
strict: bool,
|
||||
) -> RegorusResult {
|
||||
to_regorus_result(|| -> Result<()> {
|
||||
to_ref(engine)?.engine.set_strict_builtin_errors(strict);
|
||||
Ok(())
|
||||
}())
|
||||
}
|
||||
|
||||
/// Get pretty printed coverage report.
|
||||
///
|
||||
/// See https://docs.rs/regorus/latest/regorus/coverage/struct.Report.html#method.to_string_pretty
|
||||
#[no_mangle]
|
||||
#[cfg(feature = "coverage")]
|
||||
pub extern "C" fn regorus_engine_get_coverage_report_pretty(
|
||||
engine: *mut RegorusEngine,
|
||||
) -> RegorusResult {
|
||||
let output = || -> Result<String> {
|
||||
to_ref(engine)?
|
||||
.engine
|
||||
.get_coverage_report()?
|
||||
.to_string_pretty()
|
||||
}();
|
||||
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)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Clear coverage data.
|
||||
///
|
||||
/// See https://docs.rs/regorus/latest/regorus/struct.Engine.html#method.clear_coverage_data
|
||||
#[no_mangle]
|
||||
#[cfg(feature = "coverage")]
|
||||
pub extern "C" fn regorus_engine_clear_coverage_data(engine: *mut RegorusEngine) -> RegorusResult {
|
||||
to_regorus_result(|| -> Result<()> {
|
||||
to_ref(engine)?.engine.clear_coverage_data();
|
||||
Ok(())
|
||||
}())
|
||||
}
|
||||
|
||||
/// Whether to gather output of print statements.
|
||||
///
|
||||
/// See https://docs.rs/regorus/latest/regorus/struct.Engine.html#method.set_gather_prints
|
||||
/// * `enable`: Whether to enable or disable gathering print statements.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn regorus_engine_set_gather_prints(
|
||||
engine: *mut RegorusEngine,
|
||||
enable: bool,
|
||||
) -> RegorusResult {
|
||||
to_regorus_result(|| -> Result<()> {
|
||||
to_ref(engine)?.engine.set_gather_prints(enable);
|
||||
Ok(())
|
||||
}())
|
||||
}
|
||||
|
||||
/// Take all the gathered print statements.
|
||||
///
|
||||
/// See https://docs.rs/regorus/latest/regorus/struct.Engine.html#method.take_prints
|
||||
#[no_mangle]
|
||||
pub extern "C" fn regorus_engine_take_prints(engine: *mut RegorusEngine) -> RegorusResult {
|
||||
let output = || -> Result<String> {
|
||||
Ok(serde_json::to_string_pretty(
|
||||
&to_ref(engine)?.engine.take_prints()?,
|
||||
)?)
|
||||
}();
|
||||
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)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get AST of policies.
|
||||
///
|
||||
/// See https://docs.rs/regorus/latest/regorus/coverage/struct.Engine.html#method.get_ast_as_json
|
||||
#[no_mangle]
|
||||
#[cfg(feature = "ast")]
|
||||
pub extern "C" fn regorus_engine_get_ast_as_json(engine: *mut RegorusEngine) -> RegorusResult {
|
||||
let output = || -> Result<String> { to_ref(engine)?.engine.get_ast_as_json() }();
|
||||
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)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the package names defined in each policy added to the engine.
|
||||
///
|
||||
/// See https://docs.rs/regorus/latest/regorus/coverage/struct.Engine.html#method.get_policy_package_names
|
||||
#[no_mangle]
|
||||
#[cfg(feature = "azure_policy")]
|
||||
pub extern "C" fn regorus_engine_get_policy_package_names(
|
||||
engine: *mut RegorusEngine,
|
||||
) -> RegorusResult {
|
||||
let output = || -> Result<String> {
|
||||
serde_json::to_string_pretty(&to_ref(engine)?.engine.get_policy_package_names()?)
|
||||
.map_err(anyhow::Error::msg)
|
||||
}();
|
||||
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)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the parameters defined in each policy added to the engine.
|
||||
///
|
||||
/// See https://docs.rs/regorus/latest/regorus/coverage/struct.Engine.html#method.get_policy_parameters
|
||||
#[no_mangle]
|
||||
#[cfg(feature = "azure_policy")]
|
||||
pub extern "C" fn regorus_engine_get_policy_parameters(
|
||||
engine: *mut RegorusEngine,
|
||||
) -> RegorusResult {
|
||||
let output = || -> Result<String> {
|
||||
serde_json::to_string_pretty(&to_ref(engine)?.engine.get_policy_parameters()?)
|
||||
.map_err(anyhow::Error::msg)
|
||||
}();
|
||||
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)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Enable/disable rego v1.
|
||||
///
|
||||
/// See https://docs.rs/regorus/latest/regorus/struct.Engine.html#method.set_rego_v0
|
||||
#[no_mangle]
|
||||
pub extern "C" fn regorus_engine_set_rego_v0(
|
||||
engine: *mut RegorusEngine,
|
||||
enable: bool,
|
||||
) -> RegorusResult {
|
||||
let output = || -> Result<()> {
|
||||
to_ref(engine)?.engine.set_rego_v0(enable);
|
||||
Ok(())
|
||||
}();
|
||||
match output {
|
||||
Ok(()) => RegorusResult {
|
||||
status: RegorusStatus::RegorusStatusOk,
|
||||
output: std::ptr::null_mut(),
|
||||
error_message: std::ptr::null_mut(),
|
||||
},
|
||||
Err(e) => to_regorus_result(Err(e)),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "custom_allocator")]
|
||||
extern "C" {
|
||||
fn regorus_aligned_alloc(alignment: usize, size: usize) -> *mut u8;
|
||||
fn regorus_free(ptr: *mut u8);
|
||||
}
|
||||
|
||||
#[cfg(feature = "custom_allocator")]
|
||||
mod allocator {
|
||||
use std::alloc::{GlobalAlloc, Layout};
|
||||
|
||||
struct RegorusAllocator {}
|
||||
|
||||
unsafe impl GlobalAlloc for RegorusAllocator {
|
||||
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
|
||||
let size = layout.size();
|
||||
let align = layout.align();
|
||||
|
||||
crate::regorus_aligned_alloc(align, size)
|
||||
}
|
||||
|
||||
unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
|
||||
crate::regorus_free(ptr)
|
||||
}
|
||||
}
|
||||
|
||||
#[global_allocator]
|
||||
static ALLOCATOR: RegorusAllocator = RegorusAllocator {};
|
||||
}
|
||||
mod allocator;
|
||||
mod common;
|
||||
mod compile;
|
||||
mod compiled_policy;
|
||||
mod effect_registry;
|
||||
mod engine;
|
||||
mod schema_registry;
|
||||
mod target_registry;
|
||||
|
||||
Reference in New Issue
Block a user