1use std::fmt;
4
5#[derive(Debug)]
7#[non_exhaustive]
8pub enum Error {
9 AllProvidersFailed(Vec<ProviderError>),
11
12 NoProvidersForVersion,
14
15 ConsensusNotReached {
17 required: usize,
19 got: usize,
21 errors: Vec<ProviderError>,
23 },
24}
25
26impl fmt::Display for Error {
27 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28 match self {
29 Error::AllProvidersFailed(errors) => write!(f, "all providers failed: {:?}", errors),
30 Error::NoProvidersForVersion => {
31 write!(f, "no providers support the requested IP version")
32 }
33 Error::ConsensusNotReached {
34 required,
35 got,
36 errors,
37 } => {
38 write!(
39 f,
40 "consensus not reached (required {}, got {}, {} provider errors)",
41 required,
42 got,
43 errors.len()
44 )
45 }
46 }
47 }
48}
49
50impl std::error::Error for Error {}
51
52#[derive(Debug)]
54pub struct ProviderError {
55 pub provider: String,
57 pub error: Box<dyn std::error::Error + Send + Sync>,
59}
60
61impl fmt::Display for ProviderError {
62 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63 write!(f, "{}: {}", self.provider, self.error)
64 }
65}
66
67impl std::error::Error for ProviderError {
68 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
69 Some(self.error.as_ref())
70 }
71}
72
73impl ProviderError {
74 pub fn new<E>(provider: impl Into<String>, error: E) -> Self
76 where
77 E: std::error::Error + Send + Sync + 'static,
78 {
79 Self {
80 provider: provider.into(),
81 error: Box::new(error),
82 }
83 }
84
85 pub fn message(provider: impl Into<String>, msg: impl Into<String>) -> Self {
87 Self {
88 provider: provider.into(),
89 error: Box::new(StringError(msg.into())),
90 }
91 }
92}
93
94#[derive(Debug)]
95struct StringError(String);
96
97impl fmt::Display for StringError {
98 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
99 write!(f, "{}", self.0)
100 }
101}
102
103impl std::error::Error for StringError {}