use std::cell::RefCell;
pub type Result<T> = std::result::Result<T, crate::C2paError>;
thread_local! {
static LAST_ERROR: RefCell<Option<CimplError>> = const { RefCell::new(None) };
}
#[derive(Debug, Clone)]
pub struct CimplError {
code: i32,
message: String,
}
impl CimplError {
pub fn new<S: Into<String>>(code: i32, message: S) -> Self {
Self {
code,
message: message.into(),
}
}
pub fn code(&self) -> i32 {
self.code
}
pub fn message(&self) -> &str {
&self.message
}
pub fn null_parameter<S: Into<String>>(param: S) -> Self {
Self::new(1, format!("NullParameter: {}", param.into()))
}
pub fn string_too_long<S: Into<String>>(param: S) -> Self {
Self::new(2, format!("StringTooLong: {}", param.into()))
}
pub fn untracked_pointer(ptr: u64) -> Self {
Self::new(3, format!("UntrackedPointer: 0x{:x}", ptr))
}
pub fn wrong_pointer_type(ptr: u64) -> Self {
Self::new(4, format!("WrongPointerType: 0x{:x}", ptr))
}
pub fn mutex_poisoned() -> Self {
Self::new(6, "MutexPoisoned: thread panic detected".to_string())
}
pub fn invalid_buffer_size(size: usize, param: &str) -> Self {
Self::new(7, format!("InvalidBufferSize: {} for '{}'", size, param))
}
pub fn other<S: Into<String>>(msg: S) -> Self {
Self::new(5, format!("Other: {}", msg.into()))
}
pub fn last_message() -> Option<String> {
LAST_ERROR.with(|prev| prev.borrow().as_ref().map(|e| e.message.clone()))
}
pub fn last_code() -> i32 {
LAST_ERROR.with(|prev| prev.borrow().as_ref().map(|e| e.code).unwrap_or(0))
}
pub fn set_last(self) {
LAST_ERROR.with(|prev| *prev.borrow_mut() = Some(self));
}
pub fn take_last() -> Option<CimplError> {
LAST_ERROR.with(|prev| prev.borrow_mut().take())
}
}
impl std::fmt::Display for CimplError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.message)
}
}
impl std::error::Error for CimplError {}