api_err/
category.rs

1use crate::Error;
2
3/// What type of error this is. Roughly corresponds to HTTP error statuses.
4#[derive(Debug, Clone, PartialEq, Eq)]
5#[non_exhaustive]
6// TODO(shelbyd): Macro for cases.
7pub enum Category {
8    /// The client made an invalid request. Usually bad input.
9    BadRequest,
10
11    /// Fallback for custom error statuses. Will have fields based on if the `http`/`json_rpc` features are defined.
12    #[non_exhaustive]
13    Custom {
14        /// Status code for HTTP.
15        #[cfg(feature = "http")]
16        http_status: u16,
17
18        /// Status code for JSON-RPC.
19        #[cfg(feature = "json_rpc")]
20        json_rpc_status: i32,
21    },
22}
23
24/// Convenience trait for easily adding categories to errors.
25pub trait CategoryExt {
26    /// The type that is returned from this trait's functions.
27    type Ret;
28
29    /// For internal use.
30    fn _internal_error_mut(self, f: impl FnOnce(&mut Error)) -> Self::Ret;
31
32    /// Convenience trait for easily adding categories to errors.
33    fn with_category(self, category: Category) -> Self::Ret
34    where
35        Self: Sized,
36    {
37        self._internal_error_mut(|e| e.category = Some(category))
38    }
39
40    /// Convenience method for [Category::BadRequest].
41    fn bad_request(self) -> Self::Ret
42    where
43        Self: Sized,
44    {
45        self.with_category(Category::BadRequest)
46    }
47}
48
49impl<T, E> CategoryExt for Result<T, E>
50where
51    E: Into<Error>,
52{
53    type Ret = Result<T, Error>;
54
55    fn _internal_error_mut(self, f: impl FnOnce(&mut Error)) -> Self::Ret {
56        match self {
57            Ok(t) => Ok(t),
58            Err(e) => {
59                let mut e = e.into();
60                f(&mut e);
61                Err(e)
62            }
63        }
64    }
65}