use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use super::{NotificationPayload, Params};
pub const JSON_RPC_VERSION: &str = "2.0";
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(bound = "I: Serialize + DeserializeOwned")]
pub struct WsSubscribeResponse<I> {
pub status: String,
#[serde(rename = "subId")]
pub sub_id: I,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(bound = "I: Serialize + DeserializeOwned")]
pub struct WsUnsubscribeResponse<I> {
pub status: String,
#[serde(rename = "subId")]
pub sub_id: I,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(bound = "T: Serialize + DeserializeOwned, I: Serialize + DeserializeOwned")]
pub struct NotificationInner<T, I>
where
T: Clone,
{
#[serde(rename = "subId")]
pub sub_id: I,
pub payload: NotificationPayload<T>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(bound = "I: Serialize + DeserializeOwned")]
#[serde(untagged)]
pub enum WsResponseResult<I> {
Subscribe(WsSubscribeResponse<I>),
Unsubscribe(WsUnsubscribeResponse<I>),
}
impl<I> From<WsSubscribeResponse<I>> for WsResponseResult<I> {
fn from(response: WsSubscribeResponse<I>) -> Self {
WsResponseResult::Subscribe(response)
}
}
impl<I> From<WsUnsubscribeResponse<I>> for WsResponseResult<I> {
fn from(response: WsUnsubscribeResponse<I>) -> Self {
WsResponseResult::Unsubscribe(response)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(bound = "I: Serialize + DeserializeOwned")]
pub struct WsUnsubscribeRequest<I> {
#[serde(rename = "subId")]
pub sub_id: I,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case", tag = "method", content = "params")]
#[serde(bound = "I: Serialize + DeserializeOwned")]
pub enum WsMethodRequest<I> {
Subscribe(Params<I>),
Unsubscribe(WsUnsubscribeRequest<I>),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(bound = "I: Serialize + DeserializeOwned")]
pub struct WsRequest<I> {
pub jsonrpc: String,
#[serde(flatten)]
pub method: WsMethodRequest<I>,
pub id: usize,
}
impl<I> From<(WsMethodRequest<I>, usize)> for WsRequest<I> {
fn from((method, id): (WsMethodRequest<I>, usize)) -> Self {
WsRequest {
jsonrpc: JSON_RPC_VERSION.to_owned(),
method,
id,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WsNotification<T> {
pub jsonrpc: String,
pub method: String,
pub params: T,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct WsErrorBody {
pub code: i32,
pub message: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(bound = "I: Serialize + DeserializeOwned")]
pub struct WsResponse<I> {
pub jsonrpc: String,
pub result: WsResponseResult<I>,
pub id: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WsErrorResponse {
pub jsonrpc: String,
pub error: WsErrorBody,
pub id: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(bound = "I: Serialize + DeserializeOwned")]
#[serde(untagged)]
pub enum WsMessageOrResponse<I> {
Response(WsResponse<I>),
ErrorResponse(WsErrorResponse),
Notification(Box<WsNotification<NotificationInner<String, I>>>),
}
impl<I> From<(usize, Result<WsResponseResult<I>, WsErrorBody>)> for WsMessageOrResponse<I> {
fn from((id, result): (usize, Result<WsResponseResult<I>, WsErrorBody>)) -> Self {
match result {
Ok(result) => WsMessageOrResponse::Response(WsResponse {
jsonrpc: JSON_RPC_VERSION.to_owned(),
result,
id,
}),
Err(err) => WsMessageOrResponse::ErrorResponse(WsErrorResponse {
jsonrpc: JSON_RPC_VERSION.to_owned(),
error: err,
id,
}),
}
}
}