1use crate::C;
2use crate::*;
3
4pub struct CapeErrorImpl {
11 interface: C::ICapeError,
12 text: String,
13 scope: String,
14 source: String,
15 cause: Option<CapeError>,
16 reference_count: i32,
17}
18
19impl CapeErrorImpl {
20 pub fn new(err: &COBIAError, scope: &str, source: &str) -> *mut C::ICapeError {
21 let mut cause: Option<CapeError>=None;
22 let text = match err {
23 COBIAError::Message(s) => String::from(s),
24 COBIAError::Code(code) => {
25 let mut s = CapeStringImpl::new();
26 let res = unsafe { C::capeGetErrorDescription(*code, (&s.as_cape_string_out() as *const C::ICapeString).cast_mut()) };
27 if res == COBIAERR_NOERROR {
28 s.to_string()
29 } else {
30 format!("COBIA error code: {}", code)
31 }
32 },
33 COBIAError::CAPEOPEN(err) => {
34 cause=err.get_cause();
35 err.get_error_text().unwrap()
36 },
37 COBIAError::MessageWithCause(msg, because) => {
38 cause=Some(because.clone());
39 msg.clone()
40 },
41 };
42 let err_ptr = Box::into_raw(Box::new(CapeErrorImpl { interface: C::ICapeError {
44 vTbl: &CapeErrorImpl::VTABLE as *const C::ICapeError_VTable
45 as *mut C::ICapeError_VTable,
46 me: std::ptr::null_mut(),
47 },
48 text,
49 source: source.to_string(),
50 cause,
51 scope: scope.to_string(),
52 reference_count: 1, }));
54 unsafe {
55 (*err_ptr).interface.me = (err_ptr as *mut CapeErrorImpl) as *mut std::ffi::c_void;
56 &mut (*err_ptr).interface as *mut C::ICapeError
57 }
58 }
59
60 extern "C" fn add_reference(me: *mut ::std::os::raw::c_void) {
61 let p: *mut CapeErrorImpl = me as *mut CapeErrorImpl;
62 unsafe {
63 (*p).reference_count += 1;
64 }
65 }
66
67 extern "C" fn release(me: *mut ::std::os::raw::c_void) {
68 let p = me as *mut CapeErrorImpl;
69 unsafe {
70 (*p).reference_count -= 1;
71 if (*p).reference_count == 0 {
72 drop(Box::from_raw(p));
73 }
74 }
75 }
76
77 extern "C" fn get_error_text(
78 me: *mut ::std::os::raw::c_void,
79 error_text: *mut C::ICapeString,
80 ) -> CapeResult {
81 let p = me as *mut CapeErrorImpl;
82 if error_text.is_null() {
83 COBIAERR_NULLPOINTER
84 } else {
85 let mut error_text=unsafe{*((&error_text as *const *mut crate::C::ICapeString) as *mut *mut crate::C::ICapeString)};
86 let error_text=CapeStringOut::new(&mut error_text);
87 match unsafe { error_text.set_string(&(*p).text) } {
88 Ok(_) => COBIAERR_NOERROR,
89 Err(err) => match err {
90 COBIAError::Code(code) => {
91 return code;
92 }
93 _ => {
94 assert!(false);
95 return COBIAERR_UNKNOWNERROR;
96 }
97 },
98 }
99 }
100 }
101
102 extern "C" fn get_cause(
103 me: *mut ::std::os::raw::c_void,
104 cause: *mut *mut C::ICapeError,
105 ) -> CapeResult {
106 let p = me as *mut CapeErrorImpl;
107 if let Some(err) = unsafe { &(*p).cause } {
108 unsafe {
109 let e=err.interface;
110 *cause = e;
111 (*(*e).vTbl).base.addReference.unwrap()((*e).me);
112 COBIAERR_NOERROR
113 }
114 } else {
115 COBIAERR_NOSUCHITEM
116 }
117 }
118
119 extern "C" fn get_source(
120 me: *mut ::std::os::raw::c_void,
121 component_description: *mut C::ICapeString,
122 ) -> CapeResult {
123 let p = me as *mut CapeErrorImpl;
124 if component_description.is_null() {
125 COBIAERR_NULLPOINTER
126 } else {
127 let mut component_description=unsafe{*((&component_description as *const *mut crate::C::ICapeString) as *mut *mut crate::C::ICapeString)};
128 let component_description=CapeStringOut::new(&mut component_description);
129 match unsafe { component_description.set_string(&(*p).source) } {
130 Ok(_) => COBIAERR_NOERROR,
131 Err(err) => match err {
132 COBIAError::Code(code) => {
133 return code;
134 }
135 _ => {
136 assert!(false);
137 return COBIAERR_UNKNOWNERROR;
138 }
139 },
140 }
141 }
142 }
143
144 extern "C" fn get_scope(
145 me: *mut ::std::os::raw::c_void,
146 error_scope: *mut C::ICapeString,
147 ) -> CapeResult {
148 let p = me as *mut CapeErrorImpl;
149 if error_scope.is_null() {
150 COBIAERR_NULLPOINTER
151 } else {
152 let mut error_scope=unsafe{*((&error_scope as *const *mut crate::C::ICapeString) as *mut *mut crate::C::ICapeString)};
153 let error_scope=CapeStringOut::new(&mut error_scope);
154 match unsafe { error_scope.set_string(&(*p).scope) } {
155 Ok(_) => COBIAERR_NOERROR,
156 Err(err) => match err {
157 COBIAError::Code(code) => {
158 return code;
159 }
160 _ => {
161 assert!(false);
162 return COBIAERR_UNKNOWNERROR;
163 }
164 },
165 }
166 }
167 }
168
169 const VTABLE: C::ICapeError_VTable = C::ICapeError_VTable {
170 base: C::ICobiaBase_VTable {
171 addReference: Some(CapeErrorImpl::add_reference),
172 release: Some(CapeErrorImpl::release),
173 },
174 getErrorText: Some(
175 CapeErrorImpl::get_error_text
176 as unsafe extern "C" fn(
177 me: *mut ::std::os::raw::c_void,
178 errorText: *mut C::ICapeString,
179 ) -> CapeResult,
180 ),
181 getCause: Some(
182 CapeErrorImpl::get_cause
183 as unsafe extern "C" fn(
184 me: *mut ::std::os::raw::c_void,
185 cause: *mut *mut C::ICapeError,
186 ) -> CapeResult,
187 ),
188 getSource: Some(
189 CapeErrorImpl::get_source
190 as unsafe extern "C" fn(
191 me: *mut ::std::os::raw::c_void,
192 componentDescription: *mut C::ICapeString,
193 ) -> CapeResult,
194 ),
195 getScope: Some(
196 CapeErrorImpl::get_scope
197 as unsafe extern "C" fn(
198 me: *mut ::std::os::raw::c_void,
199 errorScope: *mut C::ICapeString,
200 ) -> CapeResult,
201 ),
202 };
203}
204
205
206