use super::sys;
use crate::contract::schema::SCHEMAS;
pub(super) fn schema_id(name: &str) -> u32 {
SCHEMAS.iter().find(|s| s.name == name).map_or(0, |s| s.id)
}
pub(super) fn field_at(schema: u32, name: &str) -> usize {
SCHEMAS
.get(schema as usize - 1)
.and_then(|s| s.fields.iter().position(|f| f.name == name))
.unwrap_or_else(|| panic!("the contract has no {schema}.{name}"))
}
pub(super) fn all(n: usize) -> u64 {
(1u64 << n) - 1
}
fn value(
tag: u32,
integer: i64,
real: f64,
ptr: *const std::ffi::c_void,
len: usize,
) -> sys::Value {
sys::Value {
tag,
reserved: 0,
integer,
real,
ptr,
len,
}
}
pub(super) fn text(s: &str) -> sys::Value {
value(sys::VAL_TEXT, 0, 0.0, s.as_ptr().cast(), s.len())
}
pub(super) fn int(v: i64) -> sys::Value {
value(sys::VAL_I64, v, 0.0, std::ptr::null(), 0)
}
pub(super) fn real(v: f64) -> sys::Value {
value(sys::VAL_F64, 0, v, std::ptr::null(), 0)
}
pub(super) fn enumeration(ordinal: i64) -> sys::Value {
value(sys::VAL_ENUM, ordinal, 0.0, std::ptr::null(), 0)
}
pub(super) fn texts(list: &[sys::Text]) -> sys::Value {
value(sys::VAL_TEXTS, 0, 0.0, list.as_ptr().cast(), list.len())
}
pub(super) fn rows(list: &[sys::Row]) -> sys::Value {
value(sys::VAL_ROWS, 0, 0.0, list.as_ptr().cast(), list.len())
}
pub(super) fn row(schema: u32, present: u64, values: &[sys::Value]) -> sys::Row {
sys::Row {
schema_id: schema,
nvalues: u32::try_from(values.len()).unwrap_or(u32::MAX),
present,
values: values.as_ptr(),
}
}