use base::Result;
use base::Sizable;
use base::Checkable;
use base::Serializable;
use base::Datable;
use base::Meta;
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Default, Hash, Serialize, Deserialize)]
pub struct Response<A, R>
where A: Ord + Datable,
R: Datable,
{
pub address: A,
pub meta: Meta,
pub result: Option<R>,
pub error: Option<String>,
}
impl<A, R> Response<A, R>
where A: Ord + Datable,
R: Datable
{
pub fn new(address: &A, meta: &Meta, result: Option<R>, error: Option<String>) -> Result<Self> {
address.check()?;
meta.check()?;
result.check()?;
error.check()?;
if error.is_some() && result.is_some() {
return Err(format!("invalid result"));
}
let mut response = Response {
address: address.to_owned(),
meta: meta.to_owned(),
result: result.to_owned(),
error: error.to_owned(),
};
let size = response.size();
response.meta.set_size(size);
Ok(response)
}
}
impl<A, R> Sizable for Response<A, R>
where A: Ord + Datable,
R: Datable,
{
fn size(&self) -> u64 {
self.address.size() +
self.meta.size() +
self.result.size()
}
}
impl<A, R> Checkable for Response<A, R>
where A: Ord + Datable,
R: Datable,
{
fn check(&self) -> Result<()> {
self.address.check()?;
self.meta.check()?;
self.result.check()?;
self.error.check()?;
if self.error.is_some() && self.result.is_some() {
return Err(format!("invalid result"));
}
if self.meta.get_size() != self.size() {
return Err(format!("invalid size"));
}
Ok(())
}
}
impl<A, R> Serializable for Response<A, R>
where A: Ord + Datable + Serializable,
R: Datable + Serializable,
{}
impl<A, R> Datable for Response<A, R>
where A: Ord + Datable,
R: Datable,
{}