1use std::error;
4use std::fmt;
5use std::ptr;
6
7use crate::c;
8use crate::types::{ErrSeverity, string_from};
9
10pub type TangoResult<R> = Result<R, TangoError>;
12
13
14#[derive(Debug)]
16pub struct TangoFailure {
17 pub desc: String,
18 pub reason: String,
19 pub origin: String,
20 pub severity: ErrSeverity,
21}
22
23#[derive(Debug)]
25pub struct TangoError {
26 pub failures: Vec<TangoFailure>,
27}
28
29impl fmt::Display for TangoError {
30 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
31 write!(f, "TangoError[\n")?;
32 for fail in &self.failures {
33 write!(f, "DevFailed[\n")?;
34 write!(f, " desc = {}\n", fail.desc)?;
35 write!(f, " origin = {}\n", fail.origin)?;
36 write!(f, " reason = {}\n", fail.reason)?;
37 write!(f, " severity = {:?}]\n\n", fail.severity)?;
38 }
39 write!(f, "]\n")
40 }
41}
42
43impl error::Error for TangoError {
44 fn description(&self) -> &str {
45 if self.failures.is_empty() {
46 ""
47 } else {
48 &self.failures[0].desc
49 }
50 }
51}
52
53impl TangoError {
54 pub(crate) fn from_stack(stackptr: *mut c::ErrorStack) -> TangoError {
55 let stack = unsafe { *stackptr };
56 let mut seq = Vec::with_capacity(stack.length as usize);
57 for i in 0..stack.length {
58 unsafe {
59 let df = ptr::read(stack.sequence.offset(i as isize));
60 let fail = TangoFailure {
61 desc: string_from(df.desc),
62 reason: string_from(df.reason),
63 origin: string_from(df.origin),
64 severity: ErrSeverity::from_c(df.severity)
65 };
66 seq.push(fail);
67 }
68 }
69 unsafe { c::tango_free_ErrorStack(stackptr); }
70 TangoError { failures: seq }
71 }
72}