1
2use either::Either;
3use core::error::Error;
4use core::fmt::{Debug, Display};
5
6pub struct EitherError<L, R> {
8 inner: Either<L, R>,
9}
10
11impl<L, R> AsRef<Either<L, R>> for EitherError<L, R> {
12 fn as_ref(&self) -> &Either<L, R> {
13 &self.inner
14 }
15}
16
17impl<L, R> From<Either<L, R>> for EitherError<L, R> {
18 fn from(inner: Either<L, R>) -> Self {
19 Self::new(inner)
20 }
21}
22
23impl<L, R> EitherError<L, R> {
24 pub fn new(inner: Either<L, R>) -> Self {
25 Self { inner }
26 }
27
28 pub fn into_inner(self) -> Either<L, R> {
29 self.inner
30 }
31}
32
33impl<L: Debug, R: Debug> Debug for EitherError<L, R> {
34 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
35 match &self.inner {
36 Either::Left(err) => err.fmt(f),
37 Either::Right(err) => err.fmt(f),
38 }
39 }
40}
41
42impl<L: Display, R: Display> Display for EitherError<L, R> {
43 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
44 match &self.inner {
45 Either::Left(err) => err.fmt(f),
46 Either::Right(err) => err.fmt(f),
47 }
48 }
49}
50
51impl<L, R> Error for EitherError<L, R> where L: Error, R: Error {
52 fn source(&self) -> Option<&(dyn Error + 'static)> {
53 match &self.inner {
54 Either::Left(err) => err.source(),
55 Either::Right(err) => err.source(),
56 }
57 }
58}
59
60#[cfg(all(test, feature = "alloc"))]
61mod tests {
62 extern crate alloc;
63 use super::*;
64 use alloc::format;
65
66 #[derive(Debug)]
67 struct LeftErr;
68 #[derive(Debug)]
69 struct RightErr;
70
71 impl Display for LeftErr {
72 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
73 f.write_str("left")
74 }
75 }
76
77 impl Display for RightErr {
78 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
79 f.write_str("right")
80 }
81 }
82
83 #[test]
84 fn left_formats_left() {
85 let err: EitherError<LeftErr, RightErr> = Either::Left(LeftErr).into();
86 assert_eq!(format!("{}", err), "left");
87 assert_eq!(format!("{:?}", err), "LeftErr");
88 }
89
90 #[test]
91 fn right_formats_right() {
92 let err: EitherError<LeftErr, RightErr> = Either::Right(RightErr).into();
93 assert_eq!(format!("{}", err), "right");
94 assert_eq!(format!("{:?}", err), "RightErr");
95 }
96
97 #[test]
98 fn into_inner_round_trips() {
99 let err = EitherError::<LeftErr, RightErr>::new(Either::Left(LeftErr));
100 assert!(matches!(err.into_inner(), Either::Left(LeftErr)));
101 }
102}