bbq_rs/
error.rs

1use std::{
2    alloc::{AllocError, LayoutError},
3    convert::Infallible,
4    fmt::Display,
5};
6
7use anyhow::anyhow;
8
9#[derive(Debug, Clone, Copy)]
10pub enum ErrorKind {
11    Empty,
12    Memory,
13}
14
15#[derive(Debug)]
16pub struct Error {
17    kind: ErrorKind,
18    inner: anyhow::Error,
19}
20
21impl Error {
22    pub fn new(kind: ErrorKind, inner: anyhow::Error) -> Self {
23        Self { kind, inner }
24    }
25
26    pub fn kind(&self) -> ErrorKind {
27        self.kind
28    }
29
30    pub fn into_inner(self) -> anyhow::Error {
31        self.inner
32    }
33}
34
35pub type Result<T> = std::result::Result<T, Error>;
36
37impl From<AllocError> for Error {
38    fn from(value: AllocError) -> Self {
39        Error::new(ErrorKind::Memory, anyhow!(value))
40    }
41}
42
43impl From<LayoutError> for Error {
44    fn from(value: LayoutError) -> Self {
45        Error::new(ErrorKind::Memory, anyhow!(value))
46    }
47}
48pub(crate) trait ErrorContext<T, E> {
49    type Output;
50
51    /// Wrap the error value with additional context.
52    fn context<C>(self, context: C) -> Self::Output
53    where
54        C: Display + Send + Sync + 'static;
55
56    /// Wrap the error value with additional context that is evaluated lazily
57    /// only once an error does occur.
58    fn with_context<C, F>(self, f: F) -> Self::Output
59    where
60        C: Display + Send + Sync + 'static,
61        F: FnOnce() -> C;
62}
63
64impl<T> ErrorContext<T, Infallible> for Option<T> {
65    type Output = Result<T>;
66
67    fn context<C>(self, context: C) -> Self::Output
68    where
69        C: Display + Send + Sync + 'static,
70    {
71        self.ok_or_else(|| Error::new(ErrorKind::Empty, anyhow!(context.to_string())))
72    }
73
74    fn with_context<C, F>(self, context: F) -> Self::Output
75    where
76        C: Display + Send + Sync + 'static,
77        F: FnOnce() -> C,
78    {
79        self.ok_or_else(|| Error {
80            kind: ErrorKind::Empty,
81            inner: anyhow!(context().to_string()),
82        })
83    }
84}