Skip to main content

actor_system_error/
lib.rs

1// Copyright (C) Gear Technologies Inc.
2// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
3
4//! Actor-system error.
5//!
6//! Actor is intended to be errors passed to user.
7//! System errors are to be unreachable or recoverable.
8
9#![no_std]
10
11/// Define type alias with implemented `From`s.
12#[macro_export]
13macro_rules! actor_system_error {
14    (
15        $(#[$($meta:meta)*])?
16        $vis:vis type $name:ident = ActorSystemError<$actor_err:ident, $system_err:ident>;
17    ) => {
18        $(#[$($meta)*])?
19        $vis type $name = $crate::ActorSystemError<$actor_err, $system_err>;
20
21        impl From<$actor_err> for $crate::ActorSystemError<$actor_err, $system_err> {
22            fn from(err: $actor_err) -> Self {
23                Self::Actor(err)
24            }
25        }
26
27        impl From<$system_err> for $crate::ActorSystemError<$actor_err, $system_err> {
28            fn from(err: $system_err) -> Self {
29                Self::System(err)
30            }
31        }
32    };
33}
34
35/// Actor or system error.
36#[derive(Debug, Eq, PartialEq, derive_more::Display)]
37pub enum ActorSystemError<A, S> {
38    Actor(A),
39    System(S),
40}
41
42impl<A, S> ActorSystemError<A, S> {
43    /// Map actor error.
44    pub fn map_actor<F, U>(self, f: F) -> ActorSystemError<U, S>
45    where
46        F: FnOnce(A) -> U,
47    {
48        match self {
49            Self::Actor(a) => ActorSystemError::Actor(f(a)),
50            Self::System(s) => ActorSystemError::System(s),
51        }
52    }
53
54    /// Map system error.
55    pub fn map_system<F, U>(self, f: F) -> ActorSystemError<A, U>
56    where
57        F: FnOnce(S) -> U,
58    {
59        match self {
60            Self::Actor(a) => ActorSystemError::Actor(a),
61            Self::System(s) => ActorSystemError::System(f(s)),
62        }
63    }
64
65    /// Map actor or system error using [`From::from()`].
66    pub fn map_into<UA, US>(self) -> ActorSystemError<UA, US>
67    where
68        UA: From<A>,
69        US: From<S>,
70    {
71        match self {
72            Self::Actor(a) => ActorSystemError::Actor(UA::from(a)),
73            Self::System(s) => ActorSystemError::System(US::from(s)),
74        }
75    }
76}
77
78/// Extension for [`Result`] around actor-system error.
79pub trait ResultExt<T, A, S> {
80    /// Map actor error.
81    fn map_actor_err<F, U>(self, f: F) -> Result<T, ActorSystemError<U, S>>
82    where
83        F: FnOnce(A) -> U;
84
85    /// Map system error.
86    fn map_system_err<F, U>(self, f: F) -> Result<T, ActorSystemError<A, U>>
87    where
88        F: FnOnce(S) -> U;
89
90    /// Map actor or system error.
91    fn map_err_into<UA, US>(self) -> Result<T, ActorSystemError<UA, US>>
92    where
93        UA: From<A>,
94        US: From<S>;
95}
96
97impl<T, A, S> ResultExt<T, A, S> for Result<T, ActorSystemError<A, S>> {
98    fn map_actor_err<F, U>(self, f: F) -> Result<T, ActorSystemError<U, S>>
99    where
100        F: FnOnce(A) -> U,
101    {
102        self.map_err(|err| err.map_actor(f))
103    }
104
105    fn map_system_err<F, U>(self, f: F) -> Result<T, ActorSystemError<A, U>>
106    where
107        F: FnOnce(S) -> U,
108    {
109        self.map_err(|err| err.map_system(f))
110    }
111
112    fn map_err_into<UA, US>(self) -> Result<T, ActorSystemError<UA, US>>
113    where
114        UA: From<A>,
115        US: From<S>,
116    {
117        self.map_err(ActorSystemError::map_into)
118    }
119}