Skip to main content

llama_cpp_bindings/
ffi_error_reader.rs

1use std::ffi::{CStr, c_char};
2
3/// # Safety
4///
5/// `error_ptr` must be either null or a valid pointer to a null-terminated
6/// C string allocated by `llama_rs_dup_string`.
7pub unsafe fn read_and_free_cpp_error(error_ptr: *mut c_char) -> String {
8    if error_ptr.is_null() {
9        return "unknown error".to_owned();
10    }
11
12    let message = unsafe { CStr::from_ptr(error_ptr) }
13        .to_string_lossy()
14        .into_owned();
15
16    unsafe { llama_cpp_bindings_sys::llama_rs_string_free(error_ptr) };
17
18    message
19}
20
21#[cfg(test)]
22mod tests {
23    use std::ffi::CString;
24    use std::ffi::c_char;
25
26    use super::read_and_free_cpp_error;
27
28    unsafe extern "C" {
29        fn strdup(s: *const c_char) -> *mut c_char;
30    }
31
32    #[test]
33    fn returns_unknown_for_null_pointer() {
34        let result = unsafe { read_and_free_cpp_error(std::ptr::null_mut()) };
35
36        assert_eq!(result, "unknown error");
37    }
38
39    #[test]
40    fn returns_message_for_valid_cstring_pointer() {
41        let original = CString::new("expected error message").unwrap();
42        let dup_ptr = unsafe { strdup(original.as_ptr()) };
43        assert!(!dup_ptr.is_null(), "strdup must allocate a copy");
44
45        let result = unsafe { read_and_free_cpp_error(dup_ptr) };
46
47        assert_eq!(result, "expected error message");
48    }
49}