#![doc = include_str!("../README.md")]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![cfg_attr(docsrs, allow(unused_attributes))]
#![deny(missing_docs)]
mod context;
mod error;
mod lang;
mod params;
mod safety_audit;
mod state;
mod sys;
pub use context::{
AlignmentHeadsPreset, Context, ContextParams, DEFAULT_DTW_MEM_SIZE, MAX_DTW_MEM_SIZE,
MIN_DTW_MEM_SIZE, ModelDims, SUPPORTED_DTW_N_TEXT_CTX, required_dtw_mem_size_for, system_info,
};
pub use error::{WhisperError, WhisperResult};
pub use lang::{Lang, lang_id_for, lang_max_id};
pub use params::{
MAX_BEAM_SIZE, MAX_INITIAL_TS_S, MAX_N_THREADS, MAX_TEMPERATURE, MIN_TEMPERATURE_INC, Params,
SamplingStrategy,
};
pub use state::{Segment, Segments, State, Token, Tokens};
pub fn version() -> Option<&'static str> {
let raw = unsafe { sys::whisper_version() };
if raw.is_null() {
return None;
}
let bytes = unsafe { core::ffi::CStr::from_ptr(raw).to_bytes() };
core::str::from_utf8(bytes).ok()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[cfg_attr(miri, ignore = "FFI: calls whisper_version")]
fn version_returns_some_string_for_healthy_build() {
let v = version().expect("whisper_version returned NULL or non-UTF-8");
assert!(!v.is_empty(), "whisper_version returned empty string");
assert!(
v.bytes().any(|b| b.is_ascii_digit()),
"version {v:?} contains no digits — looks corrupt"
);
}
#[test]
fn state_timing_shims_link_with_c_abi() {
let print_timings: unsafe extern "C" fn(*mut sys::whisper_context, *mut sys::whisper_state) =
sys::whispercpp_print_timings_with_state;
let reset_timings: unsafe extern "C" fn(*mut sys::whisper_state) =
sys::whispercpp_reset_timings_with_state;
assert_ne!(
print_timings as usize, 0,
"whispercpp_print_timings_with_state failed to link"
);
assert_ne!(
reset_timings as usize, 0,
"whispercpp_reset_timings_with_state failed to link"
);
assert_ne!(
print_timings as usize, reset_timings as usize,
"the two timing shims must be distinct symbols"
);
}
}