1use nanoid::nanoid;
2use serde::{Deserialize, Serialize};
3use serde_json::Value;
4use std::fmt;
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
7#[serde(untagged)]
8pub enum Message {
9 Request(Request),
10 Response(Response),
11 Event(Event),
12}
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
15pub struct Request {
16 pub id: String,
17 pub method: String,
18 pub params: Option<Value>,
19}
20
21impl Request {
22 pub fn new(method: &str, params: Option<Value>) -> Self {
23 Self {
24 id: nanoid!(),
25 method: method.to_string(),
26 params,
27 }
28 }
29}
30
31#[derive(Debug, Clone, Serialize, Deserialize)]
32#[serde(untagged)]
33pub enum Response {
34 Ok(RequestResult),
35 Error(RequestError),
36}
37
38impl Response {
39 pub fn id(&self) -> &str {
40 match self {
41 Response::Ok(result) => &result.id,
42 Response::Error(error) => &error.id,
43 }
44 }
45
46 pub fn is_ok(&self) -> bool {
47 matches!(self, Response::Ok(_))
48 }
49
50 pub fn is_error(&self) -> bool {
51 matches!(self, Response::Error(_))
52 }
53}
54
55#[derive(Debug, Clone, Serialize, Deserialize)]
56pub struct RequestResult {
57 pub id: String,
58 pub result: Value,
59}
60
61#[derive(Debug, Clone, Serialize, Deserialize)]
62pub struct RequestError {
63 pub id: String,
64 pub error: ErrorBody,
65}
66
67impl fmt::Display for RequestError {
68 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69 write!(
70 f,
71 "RequestError[code={:?}]: {}",
72 self.error.code, self.error.message
73 )
74 }
75}
76
77#[derive(Debug, Clone, Serialize, Deserialize)]
78pub struct ErrorBody {
79 pub code: ErrorCode,
80 pub message: String,
81 pub data: Option<Value>,
82}
83
84impl Into<Result<Value, ErrorBody>> for ErrorBody {
85 fn into(self) -> Result<Value, ErrorBody> {
86 Err(self)
87 }
88}
89
90impl ErrorBody {
91 pub fn internal_error(message: String) -> Self {
92 Self {
93 code: StandardErrorCode::InternalError.into(),
94 message,
95 data: None,
96 }
97 }
98
99 pub fn timeout() -> Self {
100 Self {
101 code: StandardErrorCode::RequestTimeout.into(),
102 message: "Request timeout".to_string(),
103 data: None,
104 }
105 }
106}
107
108#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
109#[serde(untagged)]
110pub enum ErrorCode {
111 Standard(StandardErrorCode),
112 Custom(i32),
113}
114
115impl fmt::Display for ErrorCode {
116 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117 match self {
118 ErrorCode::Standard(code) => write!(f, "{}", code),
119 ErrorCode::Custom(code) => write!(f, "{}", code),
120 }
121 }
122}
123
124#[repr(i32)]
125#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
126pub enum StandardErrorCode {
127 NotFound = 404,
128 Unauthorized = 401,
129 RequestTimeout = 408,
130 InternalError = 500,
131 NotImplemented = 501,
132}
133
134impl Into<ErrorCode> for StandardErrorCode {
135 fn into(self) -> ErrorCode {
136 ErrorCode::Standard(self)
137 }
138}
139
140impl fmt::Display for StandardErrorCode {
141 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
142 write!(f, "{:?}", self)
143 }
144}
145
146#[derive(Debug, Clone, Serialize, Deserialize)]
147pub struct Event {
148 pub event: String,
149 pub data: Option<Value>,
150}
151
152impl Event {
153 pub fn new<T>(event: &str, data: Option<T>) -> Self
154 where
155 T: Serialize,
156 {
157 Self {
158 event: event.to_string(),
159 data: serde_json::to_value(data).ok(),
160 }
161 }
162}