use super::{Error, Id, Version};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
pub trait Response: Serialize + DeserializeOwned + Sized {
fn from_json(response: &str) -> Result<Self, Error> {
let wrapper: Wrapper<Self> = serde_json::from_str(response).map_err(Error::parse_error)?;
wrapper.into_result()
}
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(untagged)]
enum Wrapper<R> {
Success { jsonrpc: Version, id: Id, result: R },
Error {
jsonrpc: Version,
id: Id,
error: Error,
},
}
impl<R> Wrapper<R> {
pub fn version(&self) -> &Version {
match self {
Wrapper::Success { jsonrpc, .. } => jsonrpc,
Wrapper::Error { jsonrpc, .. } => jsonrpc,
}
}
#[allow(dead_code)]
pub fn id(&self) -> &Id {
match self {
Wrapper::Success { id, .. } => id,
Wrapper::Error { id, .. } => id,
}
}
pub fn into_result(self) -> Result<R, Error> {
self.version().ensure_supported()?;
match self {
Wrapper::Success { result, .. } => Ok(result),
Wrapper::Error { error, .. } => Err(error),
}
}
}