1use super::defines::AfError;
2use super::util::{dim_t, free_host};
3
4use libc::c_char;
5use std::ffi::CStr;
6use std::ops::{Deref, DerefMut};
7use std::sync::RwLock;
8
9extern "C" {
10 fn af_get_last_error(str: *mut *mut c_char, len: *mut dim_t);
11}
12
13pub type ErrorCallback = fn(AfError);
15
16pub struct Callback {
18 cb: ErrorCallback,
19}
20
21impl Callback {
22 pub fn new(callback: ErrorCallback) -> Self {
24 Self { cb: callback }
25 }
26
27 pub fn call(&self, error_code: AfError) {
29 (self.cb)(error_code)
30 }
31}
32
33pub fn handle_error_general(error_code: AfError) {
35 match error_code {
36 AfError::SUCCESS => {} _ => panic!(
38 "Error message: {}\nLast error: {}",
39 error_code,
40 get_last_error()
41 ),
42 }
43}
44
45lazy_static! {
46 static ref ERROR_HANDLER_LOCK: RwLock<Callback> =
47 RwLock::new(Callback::new(handle_error_general));
48}
49
50#[allow(clippy::match_wild_err_arm)]
77pub fn register_error_handler(cb_value: Callback) {
78 let mut gaurd = match ERROR_HANDLER_LOCK.write() {
79 Ok(g) => g,
80 Err(_) => panic!("Failed to acquire lock to register error handler"),
81 };
82
83 *gaurd.deref_mut() = cb_value;
84}
85
86#[allow(non_snake_case)]
88#[allow(clippy::match_wild_err_arm)]
89pub fn HANDLE_ERROR(error_code: AfError) {
90 let gaurd = match ERROR_HANDLER_LOCK.read() {
91 Ok(g) => g,
92 Err(_) => panic!("Failed to acquire lock while handling FFI return value"),
93 };
94
95 (*gaurd.deref()).call(error_code);
96}
97
98pub fn get_last_error() -> String {
100 let mut result: String = String::from("No Last Error");
101 let mut tmp: *mut c_char = ::std::ptr::null_mut();
102 let mut len: dim_t = 0;
103 unsafe {
104 af_get_last_error(&mut tmp, &mut len as *mut dim_t);
105 if len > 0 {
106 result = CStr::from_ptr(tmp).to_string_lossy().into_owned();
107 free_host(tmp);
108 }
109 }
110 result
111}