use nom::{
AsBytes,
number::complete::le_u8,
combinator::{rest, rest_len},
};
use super::*;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct FileData {
file_id: u8,
data: Vec<u8>,
}
impl FromBytes for FileData {
named!(from_bytes<FileData>, do_parse!(
tag!("\x52") >>
file_id: le_u8 >>
verify!(rest_len, |len| *len <= MAX_FILE_DATA_SIZE) >>
data : rest >>
(FileData { file_id, data: data.to_vec() })
));
}
impl ToBytes for FileData {
fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> {
do_gen!(buf,
gen_be_u8!(0x52) >>
gen_be_u8!(self.file_id) >>
gen_cond!(self.data.len() > MAX_FILE_DATA_SIZE, |buf| gen_error(buf, 0)) >>
gen_slice!(self.data.as_bytes())
)
}
}
impl FileData {
pub fn new(file_id: u8, data: Vec<u8>) -> Self {
FileData { file_id, data }
}
}
#[cfg(test)]
mod tests {
use super::*;
encode_decode_test!(
tox_crypto::crypto_init().unwrap(),
file_data_encode_decode,
FileData::new(1, vec![1,2,3,4])
);
#[test]
fn file_data_from_bytes_too_long() {
let mut data = vec![0x52, 1];
let long_data = [47; MAX_FILE_DATA_SIZE + 1];
data.extend_from_slice(&long_data);
assert!(FileData::from_bytes(&data).is_err());
}
}