1use crate::error::Error;
4use serde::{Deserialize, Deserializer, Serialize, Serializer};
5use std::fmt::Display;
6
7#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
9pub enum ErrorCode {
10 ParseError = -32700,
12
13 InvalidRequest = -32600,
15
16 MethodNotFound = -32601,
18
19 InvalidParams = -32602,
21
22 #[default]
24 InternalError = -32603,
25
26 ResourceNotFound = -32002,
28
29 UrlElicitationRequiredError = -32042,
31
32 RequestCancelled = -99999,
34
35 Timeout = -99998,
37}
38
39impl From<ErrorCode> for i32 {
40 fn from(code: ErrorCode) -> Self {
41 code as i32
42 }
43}
44
45impl TryFrom<i32> for ErrorCode {
46 type Error = ();
47
48 #[inline]
49 fn try_from(value: i32) -> Result<Self, Self::Error> {
50 match value {
51 -32700 => Ok(ErrorCode::ParseError),
52 -32600 => Ok(ErrorCode::InvalidRequest),
53 -32601 => Ok(ErrorCode::MethodNotFound),
54 -32602 => Ok(ErrorCode::InvalidParams),
55 -32603 => Ok(ErrorCode::InternalError),
56 -32002 => Ok(ErrorCode::ResourceNotFound),
57 -32042 => Ok(ErrorCode::UrlElicitationRequiredError),
58 -99999 => Ok(ErrorCode::RequestCancelled),
59 -99998 => Ok(ErrorCode::Timeout),
60 _ => Err(()),
61 }
62 }
63}
64
65impl Serialize for ErrorCode {
67 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
68 where
69 S: Serializer,
70 {
71 let code: i32 = (*self).into();
72 serializer.serialize_i32(code)
73 }
74}
75
76impl<'de> Deserialize<'de> for ErrorCode {
78 fn deserialize<D>(deserializer: D) -> Result<ErrorCode, D::Error>
79 where
80 D: Deserializer<'de>,
81 {
82 let value = i32::deserialize(deserializer)?;
83 ErrorCode::try_from(value)
84 .map_err(|_| serde::de::Error::custom(format!("Invalid error code: {value}")))
85 }
86}
87
88impl Display for ErrorCode {
89 #[inline]
90 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
91 match self {
92 ErrorCode::ParseError => write!(f, "Parse error"),
93 ErrorCode::InvalidRequest => write!(f, "Invalid request"),
94 ErrorCode::MethodNotFound => write!(f, "Method not found"),
95 ErrorCode::InvalidParams => write!(f, "Invalid parameters"),
96 ErrorCode::InternalError => write!(f, "Internal error"),
97 ErrorCode::ResourceNotFound => write!(f, "Resource not found"),
98 ErrorCode::UrlElicitationRequiredError => write!(f, "URL elicitation required error"),
99 ErrorCode::RequestCancelled => write!(f, "Request cancelled"),
100 ErrorCode::Timeout => write!(f, "Request timed out"),
101 }
102 }
103}
104
105impl From<ErrorCode> for Error {
106 fn from(code: ErrorCode) -> Self {
107 Error::new(code, code.to_string())
108 }
109}
110
111#[cfg(test)]
112mod tests {
113 use super::*;
114
115 #[test]
116 fn it_converts_to_i32() {
117 let codes = [
118 (-32700, ErrorCode::ParseError),
119 (-32600, ErrorCode::InvalidRequest),
120 (-32601, ErrorCode::MethodNotFound),
121 (-32602, ErrorCode::InvalidParams),
122 (-32603, ErrorCode::InternalError),
123 (-32002, ErrorCode::ResourceNotFound),
124 (-32042, ErrorCode::UrlElicitationRequiredError),
125 (-99999, ErrorCode::RequestCancelled),
126 (-99998, ErrorCode::Timeout),
127 ];
128
129 for (code, val) in codes {
130 let error: ErrorCode = code.try_into().unwrap();
131 assert_eq!(error, val);
132
133 let int: i32 = val.into();
134 assert_eq!(int, code);
135 }
136 }
137
138 #[test]
139 fn it_serializes_error_codes() {
140 let codes = [
141 ("-32700", ErrorCode::ParseError),
142 ("-32600", ErrorCode::InvalidRequest),
143 ("-32601", ErrorCode::MethodNotFound),
144 ("-32602", ErrorCode::InvalidParams),
145 ("-32603", ErrorCode::InternalError),
146 ("-32002", ErrorCode::ResourceNotFound),
147 ("-32042", ErrorCode::UrlElicitationRequiredError),
148 ("-99999", ErrorCode::RequestCancelled),
149 ("-99998", ErrorCode::Timeout),
150 ];
151
152 for (code, val) in codes {
153 let error = serde_json::to_string(&val).unwrap();
154 assert_eq!(error, code);
155
156 let error_code: ErrorCode = serde_json::from_str(&error).unwrap();
157 assert_eq!(error_code, val);
158 }
159 }
160}