use std::ffi::c_char;
use opendp_derive::bootstrap;
use polars::prelude::{TimeUnit, TimeZone};
use crate::{
core::FfiResult,
error::Fallible,
ffi::{any::AnyDomain, util},
};
use super::DatetimeDomain;
#[bootstrap(
rust_path = "domains/struct.DatetimeDomain",
arguments(time_unit(default = "us"), time_zone(default = b"null")),
generics(DI(suppress)),
returns(c_type = "FfiResult<AnyDomain *>")
)]
fn datetime_domain(time_unit: &str, time_zone: Option<&str>) -> Fallible<DatetimeDomain> {
let time_unit = match time_unit {
"ns" => TimeUnit::Nanoseconds,
"us" => TimeUnit::Microseconds,
"ms" => TimeUnit::Milliseconds,
_ => {
return fallible!(
MakeDomain,
"time unit ({time_unit}) must be of `ns`, `us` or `ms`, corresponding to nano-, micro-, and milliseconds"
);
}
};
Ok(DatetimeDomain {
time_unit,
time_zone: TimeZone::opt_try_new(time_zone)?,
})
}
#[unsafe(no_mangle)]
pub extern "C" fn opendp_domains__datetime_domain(
time_unit: *mut c_char,
time_zone: *mut c_char,
) -> FfiResult<*mut AnyDomain> {
let time_unit = try_!(util::to_str(time_unit));
let time_zone = util::to_str(time_zone).ok();
Ok(AnyDomain::new(try_!(datetime_domain(time_unit, time_zone)))).into()
}