use std::ffi::c_char;
use opendp_derive::bootstrap;
use crate::{
core::{FfiResult, Function, Measurement, PrivacyMap, StabilityMap, Transformation},
domains::ffi::opendp_domains__user_domain,
error::Fallible,
ffi::{
any::{
AnyDomain, AnyFunction, AnyMeasure, AnyMeasurement, AnyMetric, AnyObject,
AnyTransformation, CallbackFn, wrap_func,
},
util::{self, ExtrinsicObject},
},
measures::ffi::ExtrinsicDivergence,
metrics::ffi::opendp_metrics__user_distance,
};
use self::util::to_str;
#[bootstrap(
name = "_make_measurement",
arguments(
input_domain(hint = "Domain"),
input_metric(hint = "Metric"),
output_measure(hint = "Measure"),
function(rust_type = "$pass_through(TO)"),
privacy_map(rust_type = "$measure_distance_type(output_measure)"),
),
generics(TO(default = "ExtrinsicObject"))
)]
#[allow(dead_code)]
fn _make_measurement<TO>(
input_domain: AnyDomain,
input_metric: AnyMetric,
output_measure: AnyMeasure,
function: CallbackFn,
privacy_map: CallbackFn,
) -> Fallible<Measurement<AnyDomain, AnyMetric, AnyMeasure, AnyObject>> {
let _ = (
input_domain,
input_metric,
output_measure,
privacy_map,
function,
);
panic!("this signature only exists for code generation")
}
#[unsafe(no_mangle)]
pub extern "C" fn opendp_internal___make_measurement(
input_domain: *const AnyDomain,
input_metric: *const AnyMetric,
output_measure: *const AnyMeasure,
function: *const CallbackFn,
privacy_map: *const CallbackFn,
TO: *const c_char,
) -> FfiResult<*mut AnyMeasurement> {
let _TO = TO;
Measurement::new(
try_as_ref!(input_domain).clone(),
try_as_ref!(input_metric).clone(),
try_as_ref!(output_measure).clone(),
Function::new_fallible(wrap_func(try_as_ref!(function).clone())),
PrivacyMap::new_fallible(wrap_func(try_as_ref!(privacy_map).clone())),
)
.into()
}
#[bootstrap(
name = "_make_transformation",
arguments(
input_domain(hint = "Domain"),
input_metric(hint = "Metric"),
output_domain(hint = "Domain"),
output_metric(hint = "Metric"),
function(rust_type = "$domain_carrier_type(output_domain)"),
stability_map(rust_type = "$metric_distance_type(output_metric)"),
)
)]
#[unsafe(no_mangle)]
pub extern "C" fn opendp_internal___make_transformation(
input_domain: *const AnyDomain,
input_metric: *const AnyMetric,
output_domain: *const AnyDomain,
output_metric: *const AnyMetric,
function: *const CallbackFn,
stability_map: *const CallbackFn,
) -> FfiResult<*mut AnyTransformation> {
Transformation::new(
try_as_ref!(input_domain).clone(),
try_as_ref!(input_metric).clone(),
try_as_ref!(output_domain).clone(),
try_as_ref!(output_metric).clone(),
Function::new_fallible(wrap_func(try_as_ref!(function).clone())),
StabilityMap::new_fallible(wrap_func(try_as_ref!(stability_map).clone())),
)
.into()
}
#[bootstrap(
name = "_extrinsic_domain",
arguments(
identifier(c_type = "char *", rust_type = b"null"),
member(rust_type = "bool"),
descriptor(default = b"null", rust_type = "ExtrinsicObject")
)
)]
#[unsafe(no_mangle)]
pub extern "C" fn opendp_internal___extrinsic_domain(
identifier: *mut c_char,
member: *const CallbackFn,
descriptor: *mut ExtrinsicObject,
) -> FfiResult<*mut AnyDomain> {
opendp_domains__user_domain(identifier, member, descriptor)
}
#[bootstrap(
name = "_extrinsic_divergence",
arguments(descriptor(rust_type = "String"))
)]
#[unsafe(no_mangle)]
pub extern "C" fn opendp_internal___extrinsic_divergence(
descriptor: *mut c_char,
) -> FfiResult<*mut AnyMeasure> {
let descriptor = try_!(to_str(descriptor)).to_string();
Ok(AnyMeasure::new(ExtrinsicDivergence { descriptor })).into()
}
#[bootstrap(
name = "_extrinsic_distance",
arguments(
identifier(c_type = "char *", rust_type = b"null"),
descriptor(default = b"null", rust_type = "ExtrinsicObject")
)
)]
#[unsafe(no_mangle)]
pub extern "C" fn opendp_internal___extrinsic_distance(
identifier: *mut c_char,
descriptor: *mut ExtrinsicObject,
) -> FfiResult<*mut AnyMetric> {
opendp_metrics__user_distance(identifier, descriptor)
}
#[bootstrap(
features("contrib"),
arguments(function(rust_type = "$pass_through(TO)")),
generics(TO(default = "ExtrinsicObject"))
)]
#[allow(dead_code)]
fn _new_pure_function<TO>(function: CallbackFn) -> Fallible<AnyFunction> {
let _ = function;
panic!("this signature only exists for code generation")
}
#[unsafe(no_mangle)]
pub extern "C" fn opendp_internal___new_pure_function(
function: *const CallbackFn,
TO: *const c_char,
) -> FfiResult<*mut AnyFunction> {
let _TO = TO;
FfiResult::Ok(util::into_raw(Function::new_fallible(wrap_func(
try_as_ref!(function).clone(),
))))
}