fn version(&self) -> String {
let Some(fp) = self.vtable.version_fn else { return String::new() };
let mut _out: *mut std::ffi::c_char = std::ptr::null_mut();
let mut _out_error: *mut std::ffi::c_char = std::ptr::null_mut();
// SAFETY: fp is valid; user_data validity is the caller's responsibility.
let rc = unsafe { fp(self.user_data, &mut _out, &mut _out_error) };
if rc != 0 {
if !_out_error.is_null() {
// SAFETY: _out_error is a callee-allocated NUL-terminated string.
let _ = unsafe { std::ffi::CStr::from_ptr(_out_error) }.to_string_lossy();
if let Some(free_fn) = self.vtable.free_string {
// SAFETY: free_fn is the vtable-provided destructor for callback strings.
unsafe { free_fn(_out_error) };
}
}
return self.cached_version.clone();
}
if _out.is_null() { return self.cached_version.clone(); }
// SAFETY: _out is a callee-allocated NUL-terminated string.
let version = unsafe { std::ffi::CStr::from_ptr(_out) }.to_string_lossy().into_owned();
if let Some(free_fn) = self.vtable.free_string {
// SAFETY: free_fn is the vtable-provided destructor for callback strings.
unsafe { free_fn(_out) };
}
version
}