fluxrpc_core/
message.rs

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}