#![cfg(feature = "needle")]
use core::ffi::{CStr, c_char, c_int};
use cactus_sys::{
needle_complete, needle_last_error, needle_load, needle_models, needle_set_audio,
needle_transcribe,
};
unsafe fn last_error() -> Option<String> {
let ptr = unsafe { needle_last_error() };
if ptr.is_null() {
return None;
}
Some(
unsafe { CStr::from_ptr(ptr) }
.to_string_lossy()
.into_owned(),
)
}
#[test]
fn test_engine_links_and_reports_errors() {
unsafe {
assert_eq!(needle_models(), 0);
let mut out = [0u8; 256];
let rc = needle_complete(
c"hello".as_ptr(),
core::ptr::null(),
0,
8,
out.as_mut_ptr().cast::<c_char>(),
out.len() as c_int,
);
let error = last_error();
let envelope = CStr::from_bytes_until_nul(&out).unwrap().to_str().unwrap();
println!("complete: rc {rc}, envelope {envelope:?}, last error {error:?}");
assert!(rc < 0);
assert!(
envelope.contains("needle_init not called")
|| error.as_deref().is_some_and(|e| !e.is_empty())
);
let junk = [0u8; 64];
let rc = needle_load(junk.as_ptr(), junk.len() as u64);
let error = last_error();
println!("junk load: rc {rc}, last error {error:?}");
assert!(rc < 0);
assert!(error.is_some_and(|e| !e.is_empty()));
assert_eq!(needle_models(), 0);
let pcm = [0.0f32; 1600];
let mut out = [0u8; 1024];
let rc = needle_transcribe(
pcm.as_ptr(),
pcm.len() as c_int,
core::ptr::null(),
core::ptr::null(),
0,
out.as_mut_ptr().cast::<c_char>(),
out.len() as c_int,
);
let error = last_error();
let envelope = CStr::from_bytes_until_nul(&out).unwrap().to_str().unwrap();
println!("transcribe: rc {rc}, envelope {envelope:?}, last error {error:?}");
assert!(rc < 0);
assert!(error.is_some_and(|e| !e.is_empty()));
needle_set_audio(core::ptr::null(), core::ptr::null(), 0);
}
}