//! When calling function with dynamic library, //! function return value indicates whether function has been successfully executed. //! When function return `false`, programmer may want to know which error occurs. //! //! This module provide **thread independent** error message string storage, //! which is more like Win32 `GetLastError()` but return error message instead of error code. //! These module provided functions will be called when executing main module functions. use std::cell::RefCell; use std::ffi::{CString, c_char}; struct LastError { msg: CString, } impl LastError { fn new() -> Self { Self { msg: CString::new("").expect("empty string must be valid for CString"), } } pub fn set_msg(&mut self, msg: &str) { self.msg = CString::new(msg).expect("unexpected blank in error message output"); } pub fn get_msg(&self) -> *const c_char { self.msg.as_ptr() } pub fn clear_msg(&mut self) { self.msg = CString::new("").expect("empty string must be valid for CString"); } } thread_local! { static LAST_ERROR: RefCell = RefCell::new(LastError::new()); } /// Set thread local error message. pub fn set_last_error(msg: &str) { LAST_ERROR.with(|e| { e.borrow_mut().set_msg(msg); }); } /// Get const pointer to thread local error message string. /// If there is no error, return pointer will point to empty string. pub fn get_last_error() -> *const c_char { LAST_ERROR.with(|e| e.borrow().get_msg()) } /// Clear thread local error message (reset to empty string). pub fn clear_last_error() { LAST_ERROR.with(|e| { e.borrow_mut().clear_msg(); }); }