use byteorder::{ReadBytesExt, WriteBytesExt};
use crate::{Error, SingleValueWireFormat, WireFormat};
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub struct TransferDataRequest {
pub block_sequence_counter: u8,
pub data: Vec<u8>,
}
impl TransferDataRequest {
pub(crate) fn new(block_sequence_counter: u8, data: Vec<u8>) -> Self {
Self {
block_sequence_counter,
data,
}
}
}
impl WireFormat for TransferDataRequest {
fn decode<T: std::io::Read>(reader: &mut T) -> Result<Option<Self>, Error> {
let block_sequence_counter = reader.read_u8()?;
let mut data = Vec::new();
reader.read_to_end(&mut data)?;
Ok(Some(Self {
block_sequence_counter,
data,
}))
}
fn required_size(&self) -> usize {
1 + self.data.len()
}
fn encode<T: std::io::Write>(&self, writer: &mut T) -> Result<usize, Error> {
writer.write_u8(self.block_sequence_counter)?;
writer.write_all(&self.data)?;
Ok(self.required_size())
}
}
impl SingleValueWireFormat for TransferDataRequest {}
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub struct TransferDataResponse {
pub block_sequence_counter: u8,
pub data: Vec<u8>,
}
impl TransferDataResponse {
pub(crate) fn new(block_sequence_counter: u8, data: Vec<u8>) -> Self {
Self {
block_sequence_counter,
data,
}
}
}
impl WireFormat for TransferDataResponse {
fn decode<T: std::io::Read>(reader: &mut T) -> Result<Option<Self>, Error> {
let block_sequence_counter = reader.read_u8()?;
let mut data = Vec::new();
reader.read_to_end(&mut data)?;
Ok(Some(Self {
block_sequence_counter,
data,
}))
}
fn required_size(&self) -> usize {
1 + self.data.len()
}
fn encode<T: std::io::Write>(&self, writer: &mut T) -> Result<usize, Error> {
writer.write_u8(self.block_sequence_counter)?;
writer.write_all(&self.data)?;
Ok(self.required_size())
}
}
impl SingleValueWireFormat for TransferDataResponse {}
#[cfg(test)]
mod request {
use super::*;
#[test]
fn test_transfer_data_request() {
let bytes = [0x01, 0x02, 0x03, 0x04];
let req = TransferDataRequest::new(0x01, bytes.to_vec());
let bytes = req.data.clone();
let expected = vec![0x01, 0x02, 0x03, 0x04];
assert_eq!(1, req.block_sequence_counter);
assert_eq!(bytes, expected);
}
#[test]
fn read_request() {
let bytes = [0x01, 0x02, 0x03, 0x04];
let req = TransferDataRequest::decode_single_value(&mut bytes.as_slice()).unwrap();
let mut written_bytes = Vec::new();
let written = req.encode(&mut written_bytes).unwrap();
assert_eq!(written, written_bytes.len());
assert_eq!(written, req.required_size());
}
}
#[cfg(test)]
mod response {
use super::*;
#[test]
fn simple_response() {
let bytes = [0x01, 0x02, 0x03, 0x04];
let resp = TransferDataResponse::decode_single_value(&mut bytes.as_slice()).unwrap();
let mut written_bytes = Vec::new();
let written = resp.encode(&mut written_bytes).unwrap();
assert_eq!(written, written_bytes.len());
assert_eq!(written, resp.required_size());
}
}