use std::sync::Arc;
use serde_json::value::RawValue;
use crate::{JsonRpcMessage, JsonRpcNotification, JsonRpcRequest, JsonRpcResponse, UntypedMessage};
use crate::{schema::IntoOption, v1::schema as v1};
const PROXY_SUCCESSOR: &str = v1::PROXY_METHOD_NAMES.proxy_successor;
const PROXY_INITIALIZE: &str = v1::PROXY_METHOD_NAMES.proxy_initialize;
macro_rules! impl_proxy_jsonrpc {
($ns:ident) => {
const _: () = {
use $crate::$ns::schema::{
InitializeProxyRequest, InitializeProxyResponse, ProxyNotification, ProxyRequest,
ProxyResponse, ProxySuccessorNotification, ProxySuccessorRequest,
ProxySuccessorResponse,
};
impl_jsonrpc_request!(
InitializeProxyRequest,
InitializeProxyResponse,
"proxy/initialize"
);
impl_jsonrpc_notification!(ProxySuccessorNotification, "proxy/successor");
impl JsonRpcMessage for ProxySuccessorRequest {
fn matches_method(method: &str) -> bool {
method == PROXY_SUCCESSOR
}
fn method(&self) -> &str {
PROXY_SUCCESSOR
}
fn to_untyped_message(&self) -> Result<UntypedMessage, crate::Error> {
UntypedMessage::new(PROXY_SUCCESSOR, self)
}
fn parse_message(
method: &str,
params: &serde_json::Value,
) -> Result<Self, crate::Error> {
if method != PROXY_SUCCESSOR {
return Err(crate::Error::method_not_found());
}
crate::util::json_cast_params(params)
}
}
impl JsonRpcRequest for ProxySuccessorRequest {
type Response = ProxySuccessorResponse;
}
impl JsonRpcResponse for ProxySuccessorResponse {
fn into_json(self, _method: &str) -> Result<serde_json::Value, crate::Error> {
serde_json::from_str(self.0.get()).map_err(crate::Error::into_internal_error)
}
fn from_json(
_method: &str,
value: serde_json::Value,
) -> Result<Self, crate::Error> {
Ok(Self::new(to_raw_value(&value)?))
}
}
impl JsonRpcMessage for ProxyRequest {
fn matches_method(method: &str) -> bool {
method == PROXY_INITIALIZE || method == PROXY_SUCCESSOR
}
fn method(&self) -> &str {
<ProxyRequest>::method(self)
}
fn to_untyped_message(&self) -> Result<UntypedMessage, crate::Error> {
UntypedMessage::new(<ProxyRequest>::method(self), self)
}
fn parse_message(
method: &str,
params: &serde_json::Value,
) -> Result<Self, crate::Error> {
match method {
PROXY_INITIALIZE => crate::util::json_cast_params(params).map(
|value: InitializeProxyRequest| {
Self::InitializeProxyRequest(value.into())
},
),
PROXY_SUCCESSOR => crate::util::json_cast_params(params).map(
|value: ProxySuccessorRequest| {
Self::ProxySuccessorRequest(value.into())
},
),
_ => Err(crate::Error::method_not_found()),
}
}
}
impl JsonRpcRequest for ProxyRequest {
type Response = ProxyResponse;
}
impl JsonRpcResponse for ProxyResponse {
fn into_json(self, _method: &str) -> Result<serde_json::Value, crate::Error> {
serde_json::to_value(self).map_err(crate::Error::into_internal_error)
}
fn from_json(method: &str, value: serde_json::Value) -> Result<Self, crate::Error> {
match method {
PROXY_INITIALIZE => {
crate::util::json_cast(value).map(|value: InitializeProxyResponse| {
Self::InitializeProxyResponse(value.into())
})
}
PROXY_SUCCESSOR => ProxySuccessorResponse::from_json(method, value).map(
|value: ProxySuccessorResponse| {
Self::ProxySuccessorResponse(value.into())
},
),
_ => Err(crate::Error::method_not_found()),
}
}
}
impl JsonRpcMessage for ProxyNotification {
fn matches_method(method: &str) -> bool {
method == PROXY_SUCCESSOR
}
fn method(&self) -> &str {
<ProxyNotification>::method(self)
}
fn to_untyped_message(&self) -> Result<UntypedMessage, crate::Error> {
UntypedMessage::new(<ProxyNotification>::method(self), self)
}
fn parse_message(
method: &str,
params: &serde_json::Value,
) -> Result<Self, crate::Error> {
match method {
PROXY_SUCCESSOR => crate::util::json_cast_params(params).map(
|value: ProxySuccessorNotification| {
Self::ProxySuccessorNotification(value.into())
},
),
_ => Err(crate::Error::method_not_found()),
}
}
}
impl JsonRpcNotification for ProxyNotification {}
};
};
}
impl_proxy_jsonrpc!(v1);
#[cfg(feature = "unstable_protocol_v2")]
impl_proxy_jsonrpc!(v2);
fn to_raw_value(value: &serde_json::Value) -> Result<Arc<RawValue>, crate::Error> {
serde_json::value::to_raw_value(value)
.map(Arc::from)
.map_err(crate::Error::into_internal_error)
}
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct SuccessorMessage<M: JsonRpcMessage = UntypedMessage> {
pub message: M,
pub meta: Option<v1::Meta>,
}
impl<M: JsonRpcMessage> SuccessorMessage<M> {
#[must_use]
pub fn new(message: M) -> Self {
Self {
message,
meta: None,
}
}
#[must_use]
pub fn meta(mut self, meta: impl IntoOption<v1::Meta>) -> Self {
self.meta = meta.into_option();
self
}
}
impl<M: JsonRpcMessage> JsonRpcMessage for SuccessorMessage<M> {
fn matches_method(method: &str) -> bool {
method == PROXY_SUCCESSOR
}
fn method(&self) -> &str {
PROXY_SUCCESSOR
}
fn to_untyped_message(&self) -> Result<UntypedMessage, crate::Error> {
let UntypedMessage { method, params } = self.message.to_untyped_message()?;
let envelope = v1::ProxySuccessorRequest::new(method)
.params(to_raw_value(¶ms)?)
.meta(self.meta.clone());
UntypedMessage::new(PROXY_SUCCESSOR, envelope)
}
fn parse_message(method: &str, params: &serde_json::Value) -> Result<Self, crate::Error> {
if method != PROXY_SUCCESSOR {
return Err(crate::Error::method_not_found());
}
let envelope: v1::ProxySuccessorNotification = crate::util::json_cast_params(params)?;
if !M::matches_method(&envelope.method) {
return Err(crate::Error::method_not_found());
}
let inner_params = params
.get("params")
.cloned()
.unwrap_or(serde_json::Value::Null);
let message = M::parse_message(&envelope.method, &inner_params)?;
Ok(SuccessorMessage::new(message).meta(envelope.meta))
}
}
impl<Req: JsonRpcRequest> JsonRpcRequest for SuccessorMessage<Req> {
type Response = Req::Response;
}
impl<Notif: JsonRpcNotification> JsonRpcNotification for SuccessorMessage<Notif> {}