irox_tools/errors.rs
1// SPDX-License-Identifier: MIT
2// Copyright 2023 IROX Contributors
3//
4
5//!
6//! Macros to aid in the creation of crate-level error structs
7
8crate::cfg_feature_alloc! {
9 ///
10 /// Macro to build a fairly standard error struct.
11 /// ```ignore
12 /// extern crate alloc;
13 /// #[derive(Debug, Clone, Eq, PartialEq)]
14 /// pub struct ErrorName {
15 /// error_type: ErrorType,
16 /// msg: alloc::string::String,
17 /// }
18 /// impl core::fmt::Display for ErrorName {
19 /// fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
20 /// f.write_fmt(format_args!("{:?}: {}", self.error_type, self.msg))
21 /// }
22 /// }
23 /// #[cfg(feature = "std")]
24 /// impl std::error::Error for ErrorName {}
25 /// ```
26 #[macro_export]
27 macro_rules! impl_error {
28 ($ErrorName:ident, $ErrorType:ident) => {
29 extern crate alloc;
30 #[derive(Debug, Clone, Eq, PartialEq)]
31 pub struct $ErrorName {
32 error_type: $ErrorType,
33 msg: alloc::string::String,
34 }
35 impl core::fmt::Display for $ErrorName {
36 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
37 f.write_fmt(format_args!("{:?}: {}", self.error_type, self.msg))
38 }
39 }
40 #[cfg(feature = "std")]
41 impl std::error::Error for $ErrorName {}
42 };
43 }
44}
45///
46/// Macro to implement from converters for error types generated with [`impl_error!`]
47/// ```ignore
48/// # struct ErrorName;
49/// impl From<source> for ErrorName {
50/// fn from(value: source) -> Self {
51/// ErrorName {
52/// error_type: ty,
53/// msg: value.to_string(),
54/// }
55/// }
56/// }
57/// ```
58#[macro_export]
59macro_rules! impl_from_error {
60 ($ErrorName:ident,$source:ty,$ty:expr) => {
61 impl From<$source> for $ErrorName {
62 fn from(value: $source) -> Self {
63 Self {
64 error_type: $ty,
65 msg: value.to_string(),
66 }
67 }
68 }
69 };
70}
71
72/// Macro to template out standard builder functions for types build with [`impl_error`]
73/// ```ignore
74/// impl ErrorName {
75/// pub fn name(msg: String) -> Self {
76/// Self {
77/// error_type: ty,
78/// msg,
79/// }
80/// }
81/// pub fn name_err<T>(msg: String) -> Result<T, Self> {
82/// Err(Self::name(msg))
83/// }
84/// }
85/// ```
86#[macro_export]
87macro_rules! impl_err_fn {
88 ($ErrorName:ident, $ty:expr, $name:ident, $name_err:ident) => {
89 impl $ErrorName {
90 pub fn $name(msg: String) -> Self {
91 Self {
92 error_type: $ty,
93 msg,
94 }
95 }
96 pub fn $name_err<T>(msg: String) -> Result<T, Self> {
97 Err(Self::$name(msg))
98 }
99 }
100 };
101}