1use anyhow::Error;
6use std::fmt;
7use std::sync::Arc;
8use thiserror::Error;
9
10#[derive(Clone, Error)]
12pub struct ClonableError {
13 #[source]
14 err: Arc<Error>,
15}
16
17impl From<Error> for ClonableError {
18 fn from(err: Error) -> Self {
19 Self { err: Arc::new(err) }
20 }
21}
22
23impl fmt::Display for ClonableError {
24 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25 self.err.fmt(f)
26 }
27}
28
29impl fmt::Debug for ClonableError {
30 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31 self.err.fmt(f)
32 }
33}
34
35#[cfg(test)]
36mod tests {
37 use super::*;
38 use anyhow::format_err;
39 use thiserror::Error;
40
41 #[derive(Debug, Error, Clone)]
42 #[error("\"{}\" happened: {}", msg, cause)]
43 struct FooError {
44 msg: String,
45 #[source]
46 cause: ClonableError,
47 }
48
49 #[test]
50 fn clone() {
51 let cause = format_err!("root cause").into();
52 let err = FooError { msg: "something bad happened".to_string(), cause };
53 let cloned_err = err.clone();
54 assert_eq!(format!("{:?}", err), format!("{:?}", cloned_err));
55 }
56}