Skip to main content

ark_rest/
error.rs

1use crate::conversions::ConversionError;
2use std::error::Error as StdError;
3use std::fmt;
4
5type Source = Box<dyn StdError + Send + Sync + 'static>;
6
7pub struct Error {
8    inner: ErrorImpl,
9}
10
11struct ErrorImpl {
12    kind: Kind,
13    source: Option<Source>,
14}
15
16#[derive(Debug)]
17enum Kind {
18    Request,
19    Conversion,
20}
21
22impl Error {
23    fn new(kind: Kind) -> Self {
24        Self {
25            inner: ErrorImpl { kind, source: None },
26        }
27    }
28
29    pub(crate) fn with(mut self, source: impl Into<Source>) -> Self {
30        self.inner.source = Some(source.into());
31        self
32    }
33
34    pub(crate) fn request(source: impl Into<Source>) -> Self {
35        Error::new(Kind::Request).with(source)
36    }
37
38    pub(crate) fn conversion(source: impl Into<Source>) -> Self {
39        Error::new(Kind::Conversion).with(source)
40    }
41
42    fn description(&self) -> &str {
43        match &self.inner.kind {
44            Kind::Request => "request failed",
45            Kind::Conversion => "failed to convert between types",
46        }
47    }
48}
49
50impl fmt::Debug for Error {
51    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
52        let mut f = f.debug_tuple("ark_grpc::Error");
53
54        f.field(&self.inner.kind);
55
56        if let Some(source) = &self.inner.source {
57            f.field(source);
58        }
59
60        f.finish()
61    }
62}
63
64impl fmt::Display for Error {
65    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66        f.write_str(self.description())
67    }
68}
69
70impl StdError for Error {
71    fn source(&self) -> Option<&(dyn StdError + 'static)> {
72        self.inner
73            .source
74            .as_ref()
75            .map(|source| &**source as &(dyn StdError + 'static))
76    }
77}
78
79impl From<ConversionError> for Error {
80    fn from(value: ConversionError) -> Self {
81        Error::conversion(value)
82    }
83}