use std::sync::OnceLock;
use transcribe_cpp_sys as sys;
use crate::error::{Error, Result};
use crate::result::owned_str;
use crate::types::AbiStruct;
pub fn compiled_version() -> String {
format!(
"{}.{}.{}",
sys::TRANSCRIBE_VERSION_MAJOR,
sys::TRANSCRIBE_VERSION_MINOR,
sys::TRANSCRIBE_VERSION_PATCH
)
}
pub fn version() -> String {
owned_str(unsafe { sys::transcribe_version() })
}
pub fn version_commit() -> String {
owned_str(unsafe { sys::transcribe_version_commit() })
}
pub fn header_hash() -> &'static str {
sys::PUBLIC_HEADER_HASH
}
pub fn abi_struct_size(which: AbiStruct) -> usize {
unsafe { sys::transcribe_abi_struct_size(which.to_raw()) }
}
pub fn abi_struct_align(which: AbiStruct) -> usize {
unsafe { sys::transcribe_abi_struct_align(which.to_raw()) }
}
fn base(v: &str) -> &str {
let end = v
.find(|c: char| !(c.is_ascii_digit() || c == '.'))
.unwrap_or(v.len());
v[..end].trim_end_matches('.')
}
static GATE: OnceLock<std::result::Result<(), String>> = OnceLock::new();
pub(crate) fn ensure_compatible() -> Result<()> {
let outcome = GATE.get_or_init(|| {
let runtime = version();
let compiled = compiled_version();
if base(&runtime) == base(&compiled) {
Ok(())
} else {
Err(format!(
"loaded transcribe library is {runtime}, but these bindings \
were generated for {compiled} (base versions must match \
pre-1.0)"
))
}
});
outcome.clone().map_err(Error::VersionMismatch)
}