1#[cfg(not(feature = "std"))]
4use alloc::{boxed::Box, string::String};
5
6#[cfg(feature = "std")]
7use std::{boxed::Box, string::String};
8
9use core::fmt;
10
11pub struct NexError {
15 inner: Box<dyn fmt::Display + Send + Sync + 'static>,
16 #[cfg(feature = "std")]
17 source: Option<Box<dyn std::error::Error + Send + Sync + 'static>>,
18}
19
20impl NexError {
21 #[must_use]
23 pub fn msg<M: fmt::Display + Send + Sync + 'static>(message: M) -> Self {
24 Self {
25 inner: Box::new(message),
26 #[cfg(feature = "std")]
27 source: None,
28 }
29 }
30
31 #[must_use]
33 pub fn new(message: impl Into<String>) -> Self {
34 Self::msg(message.into())
35 }
36
37 #[cfg(feature = "std")]
39 #[must_use]
40 pub fn context<C: fmt::Display + Send + Sync + 'static>(self, ctx: C) -> Self {
41 Self {
42 inner: Box::new(format!("{}: {}", ctx, self.inner)),
43 source: self.source,
44 }
45 }
46
47 #[cfg(feature = "std")]
49 #[must_use]
50 pub fn source(&self) -> Option<&(dyn std::error::Error + Send + Sync + 'static)> {
51 self.source.as_deref()
52 }
53
54 #[cfg(feature = "std")]
56 #[must_use]
57 pub fn from_err<E, C>(err: E, ctx: C) -> Self
58 where
59 E: std::error::Error + Send + Sync + 'static,
60 C: fmt::Display + Send + Sync + 'static,
61 {
62 Self {
63 inner: Box::new(format!("{ctx}: {err}")),
64 source: Some(Box::new(err)),
65 }
66 }
67}
68
69impl fmt::Display for NexError {
70 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71 write!(f, "{}", self.inner)
72 }
73}
74
75impl fmt::Debug for NexError {
76 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77 write!(f, "NexError({})", self.inner)?;
78 #[cfg(feature = "std")]
79 if let Some(ref src) = self.source {
80 write!(f, "\n caused by: {src}")?;
81 }
82 Ok(())
83 }
84}
85
86#[cfg(feature = "std")]
87impl<E> From<E> for NexError
88where
89 E: std::error::Error + Send + Sync + 'static,
90{
91 fn from(err: E) -> Self {
92 Self {
93 inner: Box::new(err.to_string()),
94 source: Some(Box::new(err)),
95 }
96 }
97}
98
99impl From<NexError> for String {
105 fn from(err: NexError) -> Self {
106 err.to_string()
107 }
108}
109
110#[cfg(not(feature = "std"))]
111impl From<NexError> for alloc::borrow::Cow<'static, str> {
112 fn from(err: NexError) -> Self {
113 alloc::borrow::Cow::Owned(err.to_string())
114 }
115}
116
117#[cfg(feature = "std")]
118impl From<NexError> for std::borrow::Cow<'static, str> {
119 fn from(err: NexError) -> Self {
120 std::borrow::Cow::Owned(err.to_string())
121 }
122}
123
124#[cfg(feature = "serde")]
127impl serde::Serialize for NexError {
128 fn serialize<S: serde::Serializer>(
129 &self,
130 serializer: S,
131 ) -> core::result::Result<S::Ok, S::Error> {
132 serializer.serialize_str(&self.to_string())
133 }
134}