cobia/
cobia_error.rs

1use crate::*;
2
3/// A COBIA error, with description
4///
5/// Many functions in this module return a `Result` with the error 
6/// type set to `COBIAError`. A `COBIAError` can be constructed from
7///
8/// - a string message, for an internal error message
9/// - a `CapeResult` error code, for an internal message that corresponds to a predefined CAPE-OPEN error code
10/// - a `CapeError`, for an error that was returned by an external CAPE-OPEN component
11/// - a string message and a `CapeError`, for an internal error message that was caused by an external CAPE-OPEN component
12///
13/// The `COBIAError` type implements the `Error` trait, so it can be used in functions that return `Result`.
14/// The `COBIAError` type also implements the `Display` trait, so it can be formatted as a string.
15
16#[derive(Clone)]
17pub enum COBIAError {
18	Message(String),
19	MessageWithCause(String,CapeError),
20	Code(CapeResult),
21	CAPEOPEN(CapeError),
22}
23
24impl COBIAError {
25	pub fn as_code(&self) -> CapeResult {
26		//in case we can only return an error code, so COBIAERR_CAPEOPENERROR is not valid here
27		match self {
28			COBIAError::Code(code) => *code,
29			_ => COBIAERR_UNKNOWNERROR,
30		}
31	}
32	pub fn from_object<T:cape_smart_pointer::CapeSmartPointer>(code:CapeResult,object:&T) -> Self {
33		match code {
34			COBIAERR_CAPEOPENERROR => {
35				//object contains the last error
36				let e=object.last_error();
37				match e {
38					Some(err) => COBIAError::CAPEOPEN(err),
39					None => COBIAError::Code(code)
40				}
41			},
42			_ => COBIAError::Code(code)
43		}
44	}
45	pub fn from_cape_interface_pointer(code:CapeResult,interface:*mut crate::C::ICapeInterface) -> Self {
46		match code {
47			COBIAERR_CAPEOPENERROR => {
48				//object contains the last error
49				let mut err_interface : * mut C::ICapeError=std::ptr::null_mut();
50				let res=unsafe {
51					((*(*(interface as *mut C::ICapeInterface)).vTbl).getLastError.unwrap())((*interface).me,&mut err_interface as *mut *mut C::ICapeError)
52				};
53				if res==COBIAERR_NOERROR {
54					if err_interface.is_null() {
55						COBIAError::Code(COBIAERR_NULLPOINTER)
56					} else {
57						COBIAError::CAPEOPEN(CapeError::attach(err_interface))
58					}
59				} else {
60					COBIAError::Code(COBIAERR_UNKNOWNERROR)
61				}
62			},
63			_ => COBIAError::Code(code)
64		}
65	}
66}
67
68impl fmt::Display for COBIAError {
69	/// Formats the COBIA error using the given formatter.
70	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
71		match self {
72			COBIAError::Message(message) => write!(f, "{}", message),
73			COBIAError::MessageWithCause(message, cause) => write!(f, "{}, caused by {}", message,cause),
74			COBIAError::Code(code) => {
75				let mut s = CapeStringImpl::new();
76				let res = unsafe { C::capeGetErrorDescription(*code, &mut s.as_cape_string_out() as *mut C::ICapeString) };
77				if res == COBIAERR_NOERROR {
78					write!(f, "{}", s)
79				} else {
80					write!(f, "COBIA error code: {}", code)
81				}
82			},
83			COBIAError::CAPEOPEN(cape_error) => write!(f, "{}", cape_error),
84		}
85	}
86}
87
88impl std::fmt::Debug for COBIAError {
89	/// Formats the COBIA error using the given formatter.
90	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
91		std::fmt::Display::fmt(self, f)
92	}
93}
94
95/// Implements the Error trait for COBIAError
96impl error::Error for COBIAError {
97	//fn description(&self) -> &str is deprecated in favor of Display
98	//fn cause(&self) -> Option<&dyn error::Error> is deprecated in favor of source
99	fn source(&self) -> Option<&(dyn error::Error + 'static)> {
100		None
101	}
102}
103
104impl Into<String> for COBIAError {
105	fn into(self) -> String {
106		format!("{}",self)
107	}
108}