1use super::actor::AnyValue;
4use super::language;
5use super::schemas::protocol as P;
6
7use preserves::value::NestedValue;
8use preserves::value::Value;
9use preserves_schema::Codec;
10use preserves_schema::ParseError;
11
12pub type Error = P::Error<AnyValue>;
13
14impl Error {
15 pub fn msg<T: std::fmt::Display>(e: T) -> Self {
25 error(&e.to_string(), AnyValue::new(false))
26 }
27}
28
29impl std::error::Error for Error {}
30
31impl std::fmt::Display for Error {
32 fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
33 write!(f, "Error: {}; detail: {:?}", self.message, self.detail)
34 }
35}
36
37pub fn error<Detail>(message: &str, detail: Detail) -> Error where AnyValue: From<Detail> {
41 Error {
42 message: message.to_owned(),
43 detail: AnyValue::from(detail),
44 }
45}
46
47pub fn encode_error(result: Result<(), Error>) -> AnyValue {
53 match result {
54 Ok(()) => {
55 let mut r = Value::record(AnyValue::symbol("Ok"), 1);
56 r.fields_vec_mut().push(Value::record(AnyValue::symbol("tuple"), 0).finish().wrap());
57 r.finish().wrap()
58 }
59 Err(e) => {
60 let mut r = Value::record(AnyValue::symbol("Err"), 1);
61 r.fields_vec_mut().push(language().unparse(&e));
62 r.finish().wrap()
63 }
64 }
65}
66
67impl<'a> From<&'a str> for Error {
68 fn from(v: &'a str) -> Self {
69 error(v, AnyValue::new(false))
70 }
71}
72
73impl From<std::io::Error> for Error {
74 fn from(v: std::io::Error) -> Self {
75 error(&format!("{}", v), AnyValue::new(false))
76 }
77}
78
79impl From<ParseError> for Error {
80 fn from(v: ParseError) -> Self {
81 error(&format!("{}", v), AnyValue::new(false))
82 }
83}
84
85impl From<preserves::error::Error> for Error {
86 fn from(v: preserves::error::Error) -> Self {
87 error(&format!("{}", v), AnyValue::new(false))
88 }
89}
90
91impl From<Box<dyn std::error::Error>> for Error {
92 fn from(v: Box<dyn std::error::Error>) -> Self {
93 match v.downcast::<Error>() {
94 Ok(e) => *e,
95 Err(v) => error(&format!("{}", v), AnyValue::new(false)),
96 }
97 }
98}
99
100impl From<Box<dyn std::error::Error + Send + Sync + 'static>> for Error {
101 fn from(v: Box<dyn std::error::Error + Send + Sync + 'static>) -> Self {
102 match v.downcast::<Error>() {
103 Ok(e) => *e,
104 Err(v) => error(&format!("{}", v), AnyValue::new(false)),
105 }
106 }
107}