1use core::ops::Deref;
2use alloc::sync::Arc;
3
4pub struct ArcError<E> {
6 inner_error: Arc<E>,
7}
8
9impl<E> Clone for ArcError<E> {
10 fn clone(&self) -> Self {
11 Self {
12 inner_error: self.inner_error.clone(),
13 }
14 }
15}
16
17impl<E> Deref for ArcError<E> {
18 type Target = E;
19 fn deref(&self) -> &E {
20 &self.inner_error
21 }
22}
23
24impl<E: PartialEq> PartialEq for ArcError<E> {
25 fn eq(&self, other: &Self) -> bool {
26 self.inner_error == other.inner_error
27 }
28}
29
30impl<E: Eq> Eq for ArcError<E> {}
31
32impl<E> AsRef<E> for ArcError<E> {
33 fn as_ref(&self) -> &E {
34 &self.inner_error
35 }
36}
37
38impl<E> From<E> for ArcError<E> {
39 fn from(inner_error: E) -> Self {
40 Self::new(inner_error)
41 }
42}
43
44impl<E> ArcError<E> {
45 pub fn new(inner_error: E) -> Self {
46 Self {
47 inner_error: Arc::new(inner_error),
48 }
49 }
50}
51
52impl<E: core::fmt::Debug> core::fmt::Debug for ArcError<E> {
53 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
54 core::fmt::Debug::fmt(&self.inner_error, f)
55 }
56}
57
58impl<E: core::fmt::Display> core::fmt::Display for ArcError<E> {
59 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
60 core::fmt::Display::fmt(&self.inner_error, f)
61 }
62}
63
64impl<E: core::error::Error> core::error::Error for ArcError<E> {
65 fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
66 self.inner_error.source()
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73 use alloc::format;
74
75 #[derive(Debug)]
76 struct MyError;
77
78 impl core::fmt::Display for MyError {
79 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
80 f.write_str("my error")
81 }
82 }
83
84 #[test]
85 fn new_and_deref() {
86 let err = ArcError::new(MyError);
87 assert_eq!(format!("{}", *err), "my error");
88 }
89
90 #[test]
91 fn from_and_display() {
92 let err: ArcError<MyError> = MyError.into();
93 assert_eq!(format!("{}", err), "my error");
94 assert_eq!(format!("{:?}", err), "MyError");
95 }
96
97 #[test]
98 fn clone_shares_allocation() {
99 let err = ArcError::new(MyError);
100 let cloned = err.clone();
101 assert!(Arc::ptr_eq(&err.inner_error, &cloned.inner_error));
102 }
103}