scsys_core/errors/
error.rs1use super::kinds::*;
6use crate::id::AtomicId;
7#[cfg(feature = "alloc")]
8use alloc::string::{String, ToString};
9
10#[derive(Clone, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
11#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
12pub struct Error<K = String> {
13 id: AtomicId,
14 kind: Errors<K>,
15 message: String,
16}
17
18impl<K> Error<K> {
19 pub fn new(kind: impl Into<Errors<K>>, message: impl ToString) -> Self {
20 Self {
21 id: AtomicId::new(),
22 kind: kind.into(),
23 message: message.to_string(),
24 }
25 }
26
27 pub fn unknown(message: impl ToString) -> Self {
28 Self::new(Errors::<K>::unknown(), message.to_string())
29 }
30
31 pub fn id(&self) -> usize {
32 *self.id
33 }
34
35 pub fn kind(&self) -> &Errors<K> {
36 &self.kind
37 }
38
39 pub fn message(&self) -> &str {
40 &self.message
41 }
42
43 pub fn set_kind(&mut self, kind: Errors<K>) {
44 self.kind = kind;
45 }
46
47 pub fn set_message(&mut self, message: String) {
48 self.message = message;
49 }
50
51 pub fn with_kind(mut self, kind: Errors<K>) -> Self {
52 self.kind = kind;
53 self
54 }
55
56 pub fn with_message(mut self, message: String) -> Self {
57 self.message = message;
58 self
59 }
60}
61
62unsafe impl<K> Send for Error<K> {}
63
64unsafe impl<K> Sync for Error<K> {}
65
66impl<K> core::fmt::Debug for Error<K> {
67 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
68 write!(
69 f,
70 "[{kind}]: {msg}",
71 kind = self.kind(),
72 msg = self.message()
73 )
74 }
75}
76
77impl<K> core::fmt::Display for Error<K> {
78 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
79 write!(
80 f,
81 "[{kind}]: {msg}",
82 kind = self.kind(),
83 msg = self.message()
84 )
85 }
86}
87
88impl<K> core::error::Error for Error<K> {}
89
90#[cfg(feature = "alloc")]
91impl<K> From<Errors<K>> for Error<K> {
92 fn from(kind: Errors<K>) -> Self {
93 Self::new(kind, String::new())
94 }
95}
96
97macro_rules! impl_error_from {
98 ($variant:ident: $($from:ty),*) => {
99 $(
100 impl_error_from!(@impl $variant: $from);
101 )*
102 };
103 ($variant:ident<$n:path>.($($from:ty),*)) => {
104 $(impl_error_from!(@impl $variant<$n>: $from);)*
105 };
106 ($variant:ident($($n:ident)::*): $($from:ty),*) => {
107 $(
108 impl_error_from!(@impl $variant($($n)::*): $from);
109 )*
110 };
111 (@impl $variant:ident($($n:ident)::*): $from:ty) => {
112 impl<K> From<$from> for Error<K> {
113 fn from(err: $from) -> Self {
114 Self::new(Errors::$variant($($n)::*(err.into())), err.to_string())
115 }
116 }
117 };
118 (@impl $variant:ident<$n:path>: $from:ty) => {
119 impl<K> From<$from> for Error<K> {
120 fn from(err: $from) -> Self {
121 Self::new(Errors::$variant($n), err.to_string())
122 }
123 }
124 };
125 (@impl $variant:ident: $from:ty) => {
126 impl<K> From<$from> for Error<K> {
127 fn from(err: $from) -> Self {
128 Self::new(Errors::$variant, err.to_string())
129 }
130 }
131 };
132
133}
134
135impl_error_from!(Error<ExternalError::Unknown>.(String, &str));
136impl_error_from!(Parse: core::num::ParseFloatError, core::num::ParseIntError, core::str::Utf8Error);
137
138#[cfg(feature = "std")]
139impl_error_from!(Error<ExternalError::Unknown>.(Box<dyn std::error::Error>));
140#[cfg(feature = "std")]
141impl_error_from!(IO: std::io::Error);
142#[cfg(feature = "std")]
143impl_error_from!(Parse: std::string::FromUtf8Error, std::string::FromUtf16Error);