use crate::{error_code::ErrorCode, response_type::ResponseType};
use casper_types::bytesrepr::{self, FromBytes, ToBytes};
#[cfg(test)]
use casper_types::testing::TestRng;
#[cfg(test)]
use rand::Rng;
#[derive(Debug, PartialEq)]
pub struct BinaryResponseHeader {
binary_response_version: u16,
error: u16,
returned_data_type_tag: Option<u8>,
}
impl BinaryResponseHeader {
pub const BINARY_RESPONSE_VERSION: u16 = 1;
pub fn new(returned_data_type: Option<ResponseType>) -> Self {
Self {
binary_response_version: Self::BINARY_RESPONSE_VERSION,
error: ErrorCode::NoError as u16,
returned_data_type_tag: returned_data_type.map(|ty| ty as u8),
}
}
pub fn new_error(error: ErrorCode) -> Self {
Self {
binary_response_version: Self::BINARY_RESPONSE_VERSION,
error: error as u16,
returned_data_type_tag: None,
}
}
pub fn returned_data_type_tag(&self) -> Option<u8> {
self.returned_data_type_tag
}
pub fn error_code(&self) -> u16 {
self.error
}
pub fn is_success(&self) -> bool {
self.error == ErrorCode::NoError as u16
}
pub fn is_not_found(&self) -> bool {
self.error == ErrorCode::NotFound as u16
}
#[cfg(test)]
pub(crate) fn random(rng: &mut TestRng) -> Self {
let error = rng.gen();
let returned_data_type_tag = if rng.gen() { None } else { Some(rng.gen()) };
BinaryResponseHeader {
binary_response_version: Self::BINARY_RESPONSE_VERSION,
error,
returned_data_type_tag,
}
}
}
impl ToBytes for BinaryResponseHeader {
fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
let mut buffer = bytesrepr::allocate_buffer(self)?;
self.write_bytes(&mut buffer)?;
Ok(buffer)
}
fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> {
let Self {
binary_response_version,
error,
returned_data_type_tag,
} = self;
binary_response_version.write_bytes(writer)?;
error.write_bytes(writer)?;
returned_data_type_tag.write_bytes(writer)
}
fn serialized_length(&self) -> usize {
self.binary_response_version.serialized_length()
+ self.error.serialized_length()
+ self.returned_data_type_tag.serialized_length()
}
}
impl FromBytes for BinaryResponseHeader {
fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> {
let (binary_response_version, remainder) = FromBytes::from_bytes(bytes)?;
let (error, remainder) = FromBytes::from_bytes(remainder)?;
let (returned_data_type_tag, remainder) = FromBytes::from_bytes(remainder)?;
Ok((
BinaryResponseHeader {
binary_response_version,
error,
returned_data_type_tag,
},
remainder,
))
}
}
#[cfg(test)]
mod tests {
use super::*;
use casper_types::testing::TestRng;
#[test]
fn bytesrepr_roundtrip() {
let rng = &mut TestRng::new();
let val = BinaryResponseHeader::random(rng);
bytesrepr::test_serialization_roundtrip(&val);
}
}