#[macro_export]
macro_rules! rpc_success {
($result:expr_2021, $id:expr_2021) => {
$crate::ResponseBuilder::new()
.success(serde_json::json!($result))
.id($id)
.build()
};
($result:expr_2021) => {
$crate::ResponseBuilder::new()
.success(serde_json::json!($result))
.id(None)
.build()
};
}
#[macro_export]
macro_rules! rpc_error {
($code:expr_2021, $message:expr_2021, $id:expr_2021) => {
$crate::ResponseBuilder::new()
.error($crate::ErrorBuilder::new($code, $message).build())
.id($id)
.build()
};
($code:expr_2021, $message:expr_2021) => {
$crate::ResponseBuilder::new()
.error($crate::ErrorBuilder::new($code, $message).build())
.id(None)
.build()
};
}
#[macro_export]
macro_rules! rpc_error_with_data {
($code:expr_2021, $message:expr_2021, $data:expr_2021, $id:expr_2021) => {
$crate::ResponseBuilder::new()
.error(
$crate::ErrorBuilder::new($code, $message)
.data(serde_json::json!($data))
.build(),
)
.id($id)
.build()
};
($code:expr_2021, $message:expr_2021, $data:expr_2021) => {
$crate::ResponseBuilder::new()
.error(
$crate::ErrorBuilder::new($code, $message)
.data(serde_json::json!($data))
.build(),
)
.id(None)
.build()
};
}
#[macro_export]
macro_rules! rpc_invalid_params {
($message:expr_2021, $id:expr_2021) => {
rpc_error!($crate::error_codes::INVALID_PARAMS, $message, $id)
};
($message:expr_2021) => {
rpc_error!($crate::error_codes::INVALID_PARAMS, $message)
};
}
#[macro_export]
macro_rules! rpc_method_not_found {
($id:expr_2021) => {
rpc_error!(
$crate::error_codes::METHOD_NOT_FOUND,
"Method not found",
$id
)
};
() => {
rpc_error!($crate::error_codes::METHOD_NOT_FOUND, "Method not found")
};
}
#[macro_export]
macro_rules! rpc_parse_error {
($message:expr_2021, $id:expr_2021) => {
rpc_error!($crate::error_codes::PARSE_ERROR, $message, $id)
};
($message:expr_2021) => {
rpc_error!($crate::error_codes::PARSE_ERROR, $message)
};
}
#[macro_export]
macro_rules! rpc_internal_error {
($message:expr_2021, $id:expr_2021) => {
rpc_error!($crate::error_codes::INTERNAL_ERROR, $message, $id)
};
($message:expr_2021) => {
rpc_error!($crate::error_codes::INTERNAL_ERROR, $message)
};
}
#[macro_export]
macro_rules! rpc_request {
($method:expr_2021, $params:expr_2021, $id:expr_2021) => {
$crate::RequestBuilder::new($method)
.params(serde_json::json!($params))
.id(serde_json::json!($id))
.build()
};
($method:expr_2021, $id:expr_2021) => {
$crate::RequestBuilder::new($method)
.id(serde_json::json!($id))
.build()
};
($method:expr_2021) => {
$crate::RequestBuilder::new($method).build()
};
}
#[macro_export]
macro_rules! rpc_notification {
($method:expr_2021, $params:expr_2021) => {
$crate::NotificationBuilder::new($method)
.params(serde_json::json!($params))
.build()
};
($method:expr_2021) => {
$crate::NotificationBuilder::new($method).build()
};
}
#[macro_export]
macro_rules! rpc_error_obj {
($code:expr_2021, $message:expr_2021, $data:expr_2021) => {
$crate::ErrorBuilder::new($code, $message)
.data(serde_json::json!($data))
.build()
};
($code:expr_2021, $message:expr_2021) => {
$crate::ErrorBuilder::new($code, $message).build()
};
}
#[cfg(feature = "tcp")]
#[macro_export]
macro_rules! rpc_tcp_server {
($addr:expr_2021, $processor:expr_2021) => {{
let server = $crate::transports::tcp::TcpServer::builder($addr)
.processor($processor)
.build()?;
server.run()
}};
}
#[cfg(feature = "tcp-stream")]
#[macro_export]
macro_rules! rpc_tcp_stream_server {
($addr:expr_2021, $processor:expr_2021) => {
async move {
let server = $crate::transports::tcp_stream::TcpStreamServer::builder($addr)
.processor($processor)
.build()?;
server.run().await
}
};
}
#[cfg(feature = "tcp-stream")]
#[macro_export]
macro_rules! rpc_tcp_stream_client {
($addr:expr_2021) => {{
$crate::transports::tcp_stream::TcpStreamClient::builder($addr)
.build()
.connect()
}};
}
#[cfg(feature = "stateful")]
#[macro_export]
macro_rules! rpc_stateful_processor {
($context:expr_2021, $handler:expr_2021) => {
$crate::stateful::StatefulProcessor::new($context, $handler)
};
}
#[cfg(feature = "stateful")]
#[macro_export]
macro_rules! rpc_stateful_registry {
() => {
$crate::stateful::StatefulMethodRegistry::new()
};
}
#[cfg(feature = "stateful")]
#[macro_export]
macro_rules! rpc_stateful_builder {
($context:expr_2021) => {
$crate::stateful::StatefulProcessor::builder($context)
};
}
#[macro_export]
macro_rules! rpc_method {
($name:ident, $method_name:expr, $handler:expr) => {
pub struct $name;
#[async_trait::async_trait]
impl $crate::JsonRPCMethod for $name {
fn method_name(&self) -> &'static str {
$method_name
}
async fn call(
&self,
params: Option<serde_json::Value>,
id: Option<$crate::RequestId>,
) -> $crate::Response {
($handler)(params, id)
}
}
};
}
#[macro_export]
macro_rules! rpc_params {
($params:expr, $id:expr => $type:ty) => {
match $params {
Some(p) => match serde_json::from_value::<$type>(p) {
Ok(params) => params,
Err(_) => return $crate::rpc_invalid_params!("Invalid parameter format", $id),
},
None => return $crate::rpc_invalid_params!("Missing required parameters", $id),
}
};
($params:expr, $id:expr => Option<$type:ty>) => {
match $params {
Some(p) => match serde_json::from_value::<$type>(p) {
Ok(params) => Some(params),
Err(_) => return $crate::rpc_invalid_params!("Invalid parameter format", $id),
},
None => None,
}
};
}
#[macro_export]
macro_rules! rpc_try {
($result:expr, $id:expr) => {
match $result {
Ok(value) => $crate::rpc_success!(value, $id),
Err(error) => {
tracing::error!(
error = %error,
request_id = ?$id,
"method execution failed"
);
$crate::rpc_error!(
$crate::error_codes::INTERNAL_ERROR,
"Internal server error",
$id
)
},
}
};
($result:expr, $id:expr, $error_code:expr) => {
match $result {
Ok(value) => $crate::rpc_success!(value, $id),
Err(error) => {
tracing::error!(
error = %error,
request_id = ?$id,
error_code = $error_code,
"method execution failed"
);
$crate::rpc_error!(
$error_code,
"Server error",
$id
)
},
}
};
($result:expr, $id:expr, $error_code:expr, $message:expr) => {
match $result {
Ok(value) => $crate::rpc_success!(value, $id),
Err(error) => {
tracing::error!(
error = %error,
request_id = ?$id,
error_code = $error_code,
"method execution failed"
);
$crate::rpc_error!($error_code, $message, $id)
},
}
};
}
#[macro_export]
macro_rules! rpc_extract {
($response:expr) => {
$response
.result()
.cloned()
.unwrap_or_else(|| serde_json::Value::Null)
};
($response:expr => $type:ty) => {
serde_json::from_value::<$type>($crate::rpc_extract!($response)).unwrap_or_default()
};
}
#[macro_export]
macro_rules! rpc_registry_with_methods {
($($method:expr),* $(,)?) => {
$crate::MethodRegistry::new($crate::register_methods![$($method),*])
};
}
#[macro_export]
macro_rules! rpc_call_request {
($method:expr, $params:expr, $id:expr) => {
$crate::RequestBuilder::new($method)
.params(serde_json::json!($params))
.id(serde_json::json!($id))
.build()
};
($method:expr, $id:expr) => {
$crate::RequestBuilder::new($method)
.id(serde_json::json!($id))
.build()
};
}
#[macro_export]
macro_rules! rpc_validate {
($condition:expr, $message:expr, $id:expr) => {
if !($condition) {
return $crate::rpc_invalid_params!($message, $id);
}
};
}