1use crate::C;
2use crate::*;
3
4pub struct CapeError {
12 pub(crate) interface: *mut C::ICapeError,
13}
14
15impl CapeError {
16
17 pub fn from_interface_pointer(interface: *mut C::ICapeError) -> Self {
37 if interface.is_null() {
38 panic!("Null pointer in creation of CapeError");
39 }
40 unsafe {((*(*interface).vTbl).base.addReference.unwrap())((*interface).me)};
41 Self {
42 interface
43 }
44 }
45
46 pub fn attach(interface: *mut C::ICapeError) -> Self {
66 if interface.is_null() {
67 panic!("Null pointer in creation of CapeError");
68 }
69 Self {
70 interface
71 }
72 }
73
74 pub fn get_error_text(&self) -> Result<String, COBIAError> {
80 let mut s = CapeStringImpl::new();
81 let result = unsafe {
82 ((*(*self.interface).vTbl).getErrorText.unwrap())((*self.interface).me,(&s.as_cape_string_out() as *const C::ICapeString).cast_mut())
83 };
84 if result == COBIAERR_NOERROR {
85 Ok(s.as_string())
86 } else {
87 Err(COBIAError::Code(result))
88 }
89 }
90
91 pub fn get_cause(&self) -> Option<CapeError> {
97 let mut interface: *mut C::ICapeError = std::ptr::null_mut();
98 let result = unsafe {
99 ((*(*self.interface).vTbl).getCause.unwrap())(
100 (*self.interface).me,
101 &mut interface as *mut *mut C::ICapeError
102 )
103 };
104 if result != COBIAERR_NOERROR || interface.is_null() {
105 None
106 } else {
107 Some(CapeError { interface })
108 }
109 }
110
111 pub fn get_source(&self) -> Result<String, COBIAError> {
117 let mut s = CapeStringImpl::new();
118 let result = unsafe {
119 ((*(*self.interface).vTbl).getSource.unwrap())((*self.interface).me,(&s.as_cape_string_out() as *const C::ICapeString).cast_mut())
120 };
121 if result == COBIAERR_NOERROR {
122 Ok(s.as_string())
123 } else {
124 Err(COBIAError::Code(result))
125 }
126 }
127
128 pub fn get_scope(&self) -> Result<String, COBIAError> {
134 let mut s = CapeStringImpl::new();
135 let result = unsafe {
136 ((*(*self.interface).vTbl).getScope.unwrap())((*self.interface).me,(&s.as_cape_string_out() as *const C::ICapeString).cast_mut())
137 };
138 if result == COBIAERR_NOERROR {
139 Ok(s.as_string())
140 } else {
141 Err(COBIAError::Code(result))
142 }
143 }
144
145}
146
147impl std::fmt::Display for CapeError {
150
151 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
152 let mut err:Option<CapeError> = Some(self.clone());
153 while let Some(e)=err {
154 match e.get_scope() {
155 Ok(scope) => {
156 match e.get_source() {
157 Ok(source) => {
158 write!(f, "in {} of {}: ", scope, source)?;
159 },
160 _ => {
161 write!(f, "in {}", scope)?;
162 }
163 }
164 },
165 _ => {
166 match e.get_source() {
167 Ok(source) => {
168 write!(f, "{}: ", source)?;
169 },
170 _ => {}
171 }
172 }
173 }
174 match e.get_error_text() {
175 Ok(text) => {
176 write!(f, "{}", text)?;
177 },
178 _ => {
179 write!(f, "Unknown error")?;
180 }
181 }
182 err=e.get_cause();
183 if err.is_some() {
184 write!(f, ", caused by: ")?;
185 }
186 }
187 Ok(())
188 }
189}
190
191impl Drop for CapeError {
197 fn drop(&mut self) {
198 unsafe {
199 ((*(*self.interface).vTbl).base.release.unwrap())((*self.interface).me);
200 }
201 }
202}
203
204impl Clone for CapeError {
210 fn clone(&self) -> Self {
211 unsafe {
212 ((*(*self.interface).vTbl).base.addReference.unwrap())((*self.interface).me);
213 }
214 CapeError {
215 interface: self.interface,
216 }
217 }
218}
219