1#[rustfmt::skip]
2
3use serde::{Serialize, Deserialize};
4use serde::de::{Deserializer};
5use serde::ser::{Serializer};
6
7use core::fmt;
8use core::mem;
9
10pub(crate) type StrBuf = str_buf::StrBuf<31>;
11
12#[derive(Debug, PartialEq, Clone, Copy)]
14pub enum ErrorCode {
15 ParseError,
18 InvalidRequest,
20 MethodNotFound,
22 InvalidParams,
24 InternalError,
26 ServerError(i64),
28}
29
30impl ErrorCode {
31 pub const fn from_code(code: i64) -> Self {
33 match code {
34 -32700 => ErrorCode::ParseError,
35 -32600 => ErrorCode::InvalidRequest,
36 -32601 => ErrorCode::MethodNotFound,
37 -32602 => ErrorCode::InvalidParams,
38 -32603 => ErrorCode::InternalError,
39 code => ErrorCode::ServerError(code),
40 }
41 }
42
43 pub const fn code(&self) -> i64 {
45 match self {
46 ErrorCode::ParseError => -32700,
47 ErrorCode::InvalidRequest => -32600,
48 ErrorCode::MethodNotFound => -32601,
49 ErrorCode::InvalidParams => -32602,
50 ErrorCode::InternalError => -32603,
51 ErrorCode::ServerError(code) => *code,
52 }
53 }
54
55 pub const fn message(&self) -> &'static str {
57 match self {
58 ErrorCode::ParseError => "Parse error",
59 ErrorCode::InvalidRequest => "Invalid Request",
60 ErrorCode::MethodNotFound => "Method not found",
61 ErrorCode::InvalidParams => "Invalid params",
62 ErrorCode::InternalError => "Internal error",
63 ErrorCode::ServerError(_) => "Server error",
64 }
65 }
66}
67
68impl<'a> Deserialize<'a> for ErrorCode {
69 #[inline]
70 fn deserialize<D: Deserializer<'a>>(deserializer: D) -> Result<ErrorCode, D::Error> {
71 let code: i64 = Deserialize::deserialize(deserializer)?;
72 Ok(ErrorCode::from_code(code))
73 }
74}
75
76impl Serialize for ErrorCode {
77 #[inline]
78 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
79 serializer.serialize_i64(self.code())
80 }
81}
82
83#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
85#[serde(deny_unknown_fields)]
86pub struct Error<T, M=StrBuf> {
87 pub code: ErrorCode,
89 pub message: M,
91 #[serde(skip_serializing_if = "Option::is_none")]
93 pub data: Option<T>,
94}
95
96impl<'a, T, EM: From<&'a str>> Error<T, EM> {
97 #[inline]
98 pub fn with_text_message(code: ErrorCode, message: &'a str) -> Self {
100 Self {
101 code,
102 message: message.into(),
103 data: None,
104 }
105 }
106}
107
108impl<T> fmt::Display for Error<T> {
109 #[inline(always)]
110 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
111 fmt.write_str(self.code.message())
112 }
113}
114
115impl<const N: usize, T> Error<T, str_buf::StrBuf<N>> {
116 pub const fn with_custom_msg_truncated(code: ErrorCode, message: &str) -> Self {
118 let mut storage = [mem::MaybeUninit::uninit(); N];
119 let msg = message.as_bytes();
120 let mut idx = 0;
121
122 let idx_limit = if storage.len() > msg.len() {
123 msg.len()
124 } else {
125 storage.len()
126 };
127
128 loop {
129 storage[idx] = mem::MaybeUninit::new(msg[idx]);
130 idx += 1;
131 if idx == idx_limit {
132 break;
133 }
134 }
135
136 let message = unsafe {
137 str_buf::StrBuf::from_storage(storage, idx as u8)
138 };
139
140 Self {
141 code,
142 message,
143 data: None,
144 }
145 }
146
147 pub const fn with_custom_msg(code: ErrorCode, message: &str) -> Self {
149 let mut storage = [mem::MaybeUninit::uninit(); N];
150 let msg = message.as_bytes();
151 let mut idx = 0;
152 loop {
153 storage[idx] = mem::MaybeUninit::new(msg[idx]);
154 idx += 1;
155 if idx == msg.len() {
156 break;
157 }
158 }
159
160 let message = unsafe {
161 str_buf::StrBuf::from_storage(storage, msg.len() as u8)
162 };
163
164 Self {
165 code,
166 message,
167 data: None,
168 }
169 }
170
171 #[inline]
172 pub const fn from_code(code: ErrorCode) -> Self {
174 Self::with_custom_msg(code, code.message())
175 }
176
177 #[inline(always)]
178 pub fn set_data(self, data: T) -> Self {
180 Self {
181 code: self.code,
182 message: self.message,
183 data: Some(data)
184 }
185 }
186}