transcribe_cpp/
version.rs1use std::sync::OnceLock;
10
11use transcribe_cpp_sys as sys;
12
13use crate::error::{Error, Result};
14use crate::result::owned_str;
15use crate::types::AbiStruct;
16
17pub fn compiled_version() -> String {
19 format!(
20 "{}.{}.{}",
21 sys::TRANSCRIBE_VERSION_MAJOR,
22 sys::TRANSCRIBE_VERSION_MINOR,
23 sys::TRANSCRIBE_VERSION_PATCH
24 )
25}
26
27pub fn version() -> String {
29 owned_str(unsafe { sys::transcribe_version() })
30}
31
32pub fn version_commit() -> String {
34 owned_str(unsafe { sys::transcribe_version_commit() })
35}
36
37pub fn header_hash() -> &'static str {
39 sys::PUBLIC_HEADER_HASH
40}
41
42pub fn abi_struct_size(which: AbiStruct) -> usize {
44 unsafe { sys::transcribe_abi_struct_size(which.to_raw()) }
45}
46
47pub fn abi_struct_align(which: AbiStruct) -> usize {
49 unsafe { sys::transcribe_abi_struct_align(which.to_raw()) }
50}
51
52fn base(v: &str) -> &str {
54 let end = v
55 .find(|c: char| !(c.is_ascii_digit() || c == '.'))
56 .unwrap_or(v.len());
57 v[..end].trim_end_matches('.')
58}
59
60static GATE: OnceLock<std::result::Result<(), String>> = OnceLock::new();
61
62pub(crate) fn ensure_compatible() -> Result<()> {
64 let outcome = GATE.get_or_init(|| {
65 let runtime = version();
66 let compiled = compiled_version();
67 if base(&runtime) == base(&compiled) {
68 Ok(())
69 } else {
70 Err(format!(
71 "loaded transcribe library is {runtime}, but these bindings \
72 were generated for {compiled} (base versions must match \
73 pre-1.0)"
74 ))
75 }
76 });
77 outcome.clone().map_err(Error::VersionMismatch)
78}