use std::{ os::raw::{c_char, c_int}, sync::RwLock, }; static ERROR_STATUS: RwLock = RwLock::new(ErrorCode::None); #[repr(i16)] #[derive(Debug, Clone, Copy)] pub enum ErrorCode { /// No known error status. None = 0, /// Can't open file. Open = 1, /// Error reading from file. Read = 2, /// Error writing to file. Write = 3, /// Out of memory. NoMemory = 4, /// Out of color cells. NoColor = 5, /// Image file is corrupted or invalid. BadImageFile = 6, /// Image file format is unknown. BadFormat = 7, /// No such image index in file. BadIndex = 8, /// Invalid visual ID requested for context. BadVisualId = 16, /// Failed to create std colormap. StdCmapFail = 17, /// Internal X11 error. XError = 127, /// Should not happen. Internal = 128, } /// Sets the global error status in a thread-safe way. Panics if the error /// status lock has been poisoned. pub fn wraster_set_error_code(code: ErrorCode) { *ERROR_STATUS.write().unwrap() = code; } /// Sets the global error status to a literal `value`. Panics if `value` does /// not correspond to a valid error value. #[no_mangle] pub unsafe extern "C" fn wraster_report_error_code(value: c_int) { let value = match value { 0 => ErrorCode::None, 1 => ErrorCode::Open, 2 => ErrorCode::Read, 3 => ErrorCode::Write, 4 => ErrorCode::NoMemory, 5 => ErrorCode::NoColor, 6 => ErrorCode::BadImageFile, 7 => ErrorCode::BadFormat, 8 => ErrorCode::BadIndex, 16 => ErrorCode::BadVisualId, 17 => ErrorCode::StdCmapFail, 127 => ErrorCode::XError, 128 => ErrorCode::Internal, _ => panic!("unknown error code: {}", value), }; *ERROR_STATUS.write().unwrap() = value; } /// Returns the current error status. Panics if the error status lock has been /// poisoned. #[no_mangle] pub extern "C" fn wraster_current_error_code() -> i16 { *ERROR_STATUS.read().unwrap() as i16 } /// Returns a human-readable description of the current error status. Panics if /// the error status lock has been poisoned. #[no_mangle] pub extern "C" fn wraster_current_error_message() -> *const c_char { // TODO: i18n of these messages. match *ERROR_STATUS.read().unwrap() { ErrorCode::None => c"no error".as_ptr(), ErrorCode::Open => c"could not open file".as_ptr(), ErrorCode::Read => c"error reading from file".as_ptr(), ErrorCode::Write => c"error writing to file".as_ptr(), ErrorCode::NoMemory => c"out of memory".as_ptr(), ErrorCode::NoColor => c"out of color cells".as_ptr(), ErrorCode::BadImageFile => c"invalid or corrupted image file".as_ptr(), ErrorCode::BadFormat => c"image format is not supported".as_ptr(), ErrorCode::BadIndex => c"file does not contain requested image index".as_ptr(), ErrorCode::BadVisualId => c"request for an invalid Visual ID".as_ptr(), ErrorCode::StdCmapFail => c"failed to create X standard colormap".as_ptr(), ErrorCode::XError => c"internal X error".as_ptr(), ErrorCode::Internal => c"internal error".as_ptr(), } }