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 fn context<C>(self, context: C) -> Self::Output
53 where
54 C: Display + Send + Sync + 'static;
55
56 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}