core/context/
error.rs

1use std::fmt::{Display, Formatter};
2use std::sync::Arc;
3
4/// Go 语义下的上下文错误类型。
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub enum Error {
7    /// 对齐 Go 的 `context canceled`。
8    Canceled,
9    /// 对齐 Go 的 `context deadline exceeded`。
10    DeadlineExceeded,
11}
12
13impl Error {
14    pub const fn as_str(self) -> &'static str {
15        match self {
16            Error::Canceled => "context canceled",
17            Error::DeadlineExceeded => "context deadline exceeded",
18        }
19    }
20}
21
22/// Context 错误,带可选 cause。
23#[derive(Debug, Clone)]
24pub struct ContextError {
25    kind: Error,
26    cause: Option<Arc<dyn std::error::Error + Send + Sync>>,
27}
28
29impl ContextError {
30    pub const fn new(kind: Error) -> Self {
31        Self { kind, cause: None }
32    }
33
34    pub fn with_cause(
35        kind: Error,
36        cause: Option<Arc<dyn std::error::Error + Send + Sync>>,
37    ) -> Self {
38        Self { kind, cause }
39    }
40
41    pub const fn kind(&self) -> Error {
42        self.kind
43    }
44
45    pub fn cause(&self) -> Option<&Arc<dyn std::error::Error + Send + Sync>> {
46        self.cause.as_ref()
47    }
48}
49
50impl Display for ContextError {
51    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
52        if let Some(cause) = &self.cause {
53            write!(f, "{}: {cause}", self.kind.as_str())
54        } else {
55            f.write_str(self.kind.as_str())
56        }
57    }
58}
59
60impl std::error::Error for ContextError {
61    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
62        self.cause
63            .as_ref()
64            .map(|c| &**c as &(dyn std::error::Error + 'static))
65    }
66}
67
68/// Go 对齐的默认错误实例。
69pub const CANCELLED: ContextError = ContextError::new(Error::Canceled);
70pub const DEADLINE_EXCEEDED: ContextError = ContextError::new(Error::DeadlineExceeded);
71
72impl From<Error> for ContextError {
73    fn from(kind: Error) -> Self {
74        ContextError::new(kind)
75    }
76}