Files
pezkuwi-subxt/lightclient/src/rpc.rs
wgyt 396762510a update copyright year (#1924)
Co-authored-by: Niklas Adolfsson <niklasadolfsson1@gmail.com>
2025-02-24 16:07:29 +00:00

133 lines
4.0 KiB
Rust

// Copyright 2019-2025 Parity Technologies (UK) Ltd.
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
// see LICENSE for license details.
use serde::Deserialize;
use serde_json::value::RawValue;
/// The RPC response from the light-client.
/// This can either be a response of a method, or a notification from a subscription.
#[derive(Debug, Clone)]
pub enum RpcResponse {
Method {
/// Response ID.
id: String,
/// The result of the method call.
result: Box<RawValue>,
},
MethodError {
/// Response ID.
id: String,
/// Error.
error: Box<RawValue>,
},
Notification {
/// RPC method that generated the notification.
method: String,
/// Subscription ID.
subscription_id: String,
/// Result.
result: Box<RawValue>,
},
NotificationError {
/// RPC method that generated the notification.
method: String,
/// Subscription ID.
subscription_id: String,
/// Result.
error: Box<RawValue>,
},
}
impl std::str::FromStr for RpcResponse {
type Err = ();
fn from_str(response: &str) -> Result<Self, Self::Err> {
// Valid response
#[derive(Deserialize, Debug)]
struct Response {
#[allow(unused)]
jsonrpc: String,
id: String,
result: Box<RawValue>,
}
// Error response
#[derive(Deserialize)]
struct ResponseError {
#[allow(unused)]
jsonrpc: String,
id: String,
error: Box<RawValue>,
}
// Valid notification (subscription) response
#[derive(Deserialize)]
struct Notification {
#[allow(unused)]
jsonrpc: String,
method: String,
params: NotificationResultParams,
}
#[derive(Deserialize)]
struct NotificationResultParams {
subscription: String,
result: Box<RawValue>,
}
// Error notification (subscription) response
#[derive(Deserialize)]
struct NotificationError {
#[allow(unused)]
jsonrpc: String,
method: String,
params: NotificationErrorParams,
}
#[derive(Deserialize)]
struct NotificationErrorParams {
/// The ID of the subscription.
subscription: String,
error: Box<RawValue>,
}
// Try deserializing the response payload to one of the above. We can
// do this more efficiently eg how jsonrpsee_types does.
let result: Result<Response, _> = serde_json::from_str(response);
if let Ok(response) = result {
return Ok(RpcResponse::Method {
id: response.id,
result: response.result,
});
}
let result: Result<Notification, _> = serde_json::from_str(response);
if let Ok(response) = result {
return Ok(RpcResponse::Notification {
subscription_id: response.params.subscription,
method: response.method,
result: response.params.result,
});
}
let result: Result<ResponseError, _> = serde_json::from_str(response);
if let Ok(response) = result {
return Ok(RpcResponse::MethodError {
id: response.id,
error: response.error,
});
}
let result: Result<NotificationError, _> = serde_json::from_str(response);
if let Ok(response) = result {
return Ok(RpcResponse::NotificationError {
method: response.method,
subscription_id: response.params.subscription,
error: response.params.error,
});
}
// We couldn't decode into any of the above. We could pick one of the above`
// errors to return, but there's no real point since the string is obviously
// different from any of them.
Err(())
}
}