use super::{Params, RPCResponse, Serializable, ValidationError, JSON_RPC_VERSION_STR};
use crate::jwt::decode::MessageId;
use serde::{Deserialize, Serialize};
pub trait RequestPayload: Serializable {
type Error: Into<ErrorData> + Send + 'static;
type Response: Serializable;
fn validate(&self) -> Result<(), ValidationError> {
Ok(())
}
fn into_params(self) -> Params;
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum Response {
Success(SuccessfulResponse),
RPCResponse(RPCResponse),
Error(ErrorResponse),
}
impl Response {
pub fn id(&self) -> MessageId {
match self {
Self::Success(response) => response.id,
Self::RPCResponse(response) => response.id,
Self::Error(response) => response.id,
}
}
pub fn validate(&self) -> Result<(), ValidationError> {
match self {
Self::Success(response) => response.validate(),
Self::RPCResponse(response) => response.validate(),
Self::Error(response) => response.validate(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SuccessfulResponse {
pub id: MessageId,
pub jsonrpc: String,
pub result: serde_json::Value,
}
impl SuccessfulResponse {
pub fn new(id: MessageId, result: serde_json::Value) -> Self {
Self { id, jsonrpc: JSON_RPC_VERSION_STR.to_string(), result }
}
pub fn validate(&self) -> Result<(), ValidationError> {
if &self.jsonrpc != JSON_RPC_VERSION_STR {
Err(ValidationError::JsonRpcVersion)
} else {
Ok(())
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ErrorResponse {
pub id: MessageId,
pub jsonrpc: String,
pub error: ErrorData,
}
impl ErrorResponse {
pub fn new(id: MessageId, error: ErrorData) -> Self {
Self { id, jsonrpc: JSON_RPC_VERSION_STR.to_string(), error }
}
pub fn validate(&self) -> Result<(), ValidationError> {
if &self.jsonrpc != JSON_RPC_VERSION_STR {
Err(ValidationError::JsonRpcVersion)
} else {
Ok(())
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ErrorData {
pub code: i32,
pub message: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<String>,
}