actor_system_error/
lib.rs

1// This file is part of Gear.
2
3// Copyright (C) 2023-2025 Gear Technologies Inc.
4// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
5
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19//! Actor-system error.
20//!
21//! Actor is intended to be errors passed to user.
22//! System errors are to be unreachable or recoverable.
23
24#![no_std]
25
26/// Define type alias with implemented `From`s.
27#[macro_export]
28macro_rules! actor_system_error {
29    (
30        $(#[$($meta:meta)*])?
31        $vis:vis type $name:ident = ActorSystemError<$actor_err:ident, $system_err:ident>;
32    ) => {
33        $(#[$($meta)*])?
34        $vis type $name = $crate::ActorSystemError<$actor_err, $system_err>;
35
36        impl From<$actor_err> for $crate::ActorSystemError<$actor_err, $system_err> {
37            fn from(err: $actor_err) -> Self {
38                Self::Actor(err)
39            }
40        }
41
42        impl From<$system_err> for $crate::ActorSystemError<$actor_err, $system_err> {
43            fn from(err: $system_err) -> Self {
44                Self::System(err)
45            }
46        }
47    };
48}
49
50/// Actor or system error.
51#[derive(Debug, Eq, PartialEq, derive_more::Display)]
52pub enum ActorSystemError<A, S> {
53    Actor(A),
54    System(S),
55}
56
57impl<A, S> ActorSystemError<A, S> {
58    /// Map actor error.
59    pub fn map_actor<F, U>(self, f: F) -> ActorSystemError<U, S>
60    where
61        F: FnOnce(A) -> U,
62    {
63        match self {
64            Self::Actor(a) => ActorSystemError::Actor(f(a)),
65            Self::System(s) => ActorSystemError::System(s),
66        }
67    }
68
69    /// Map system error.
70    pub fn map_system<F, U>(self, f: F) -> ActorSystemError<A, U>
71    where
72        F: FnOnce(S) -> U,
73    {
74        match self {
75            Self::Actor(a) => ActorSystemError::Actor(a),
76            Self::System(s) => ActorSystemError::System(f(s)),
77        }
78    }
79
80    /// Map actor or system error using [`From::from()`].
81    pub fn map_into<UA, US>(self) -> ActorSystemError<UA, US>
82    where
83        UA: From<A>,
84        US: From<S>,
85    {
86        match self {
87            Self::Actor(a) => ActorSystemError::Actor(UA::from(a)),
88            Self::System(s) => ActorSystemError::System(US::from(s)),
89        }
90    }
91}
92
93/// Extension for [`Result`] around actor-system error.
94pub trait ResultExt<T, A, S> {
95    /// Map actor error.
96    fn map_actor_err<F, U>(self, f: F) -> Result<T, ActorSystemError<U, S>>
97    where
98        F: FnOnce(A) -> U;
99
100    /// Map system error.
101    fn map_system_err<F, U>(self, f: F) -> Result<T, ActorSystemError<A, U>>
102    where
103        F: FnOnce(S) -> U;
104
105    /// Map actor or system error.
106    fn map_err_into<UA, US>(self) -> Result<T, ActorSystemError<UA, US>>
107    where
108        UA: From<A>,
109        US: From<S>;
110}
111
112impl<T, A, S> ResultExt<T, A, S> for Result<T, ActorSystemError<A, S>> {
113    fn map_actor_err<F, U>(self, f: F) -> Result<T, ActorSystemError<U, S>>
114    where
115        F: FnOnce(A) -> U,
116    {
117        self.map_err(|err| err.map_actor(f))
118    }
119
120    fn map_system_err<F, U>(self, f: F) -> Result<T, ActorSystemError<A, U>>
121    where
122        F: FnOnce(S) -> U,
123    {
124        self.map_err(|err| err.map_system(f))
125    }
126
127    fn map_err_into<UA, US>(self) -> Result<T, ActorSystemError<UA, US>>
128    where
129        UA: From<A>,
130        US: From<S>,
131    {
132        self.map_err(ActorSystemError::map_into)
133    }
134}