use crate::byte_reader::ByteReader;
use crate::error::Result;
use byteorder::{BigEndian, WriteBytesExt};
use std::fmt;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct BootstrapMethod {
pub bootstrap_method_ref: u16,
pub arguments: Vec<u16>,
}
impl BootstrapMethod {
pub fn from_bytes(bytes: &mut ByteReader<'_>) -> Result<BootstrapMethod> {
let bootstrap_method_ref = bytes.read_u16()?;
let arguments_count = bytes.read_u16()? as usize;
let mut arguments = Vec::with_capacity(arguments_count);
for _ in 0..arguments_count {
arguments.push(bytes.read_u16()?);
}
let bootstrap_method = BootstrapMethod {
bootstrap_method_ref,
arguments,
};
Ok(bootstrap_method)
}
pub fn to_bytes(&self, bytes: &mut Vec<u8>) -> Result<()> {
bytes.write_u16::<BigEndian>(self.bootstrap_method_ref)?;
let arguments_length = u16::try_from(self.arguments.len())?;
bytes.write_u16::<BigEndian>(arguments_length)?;
for argument in &self.arguments {
bytes.write_u16::<BigEndian>(*argument)?;
}
Ok(())
}
}
impl fmt::Display for BootstrapMethod {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"bootstrap_method_ref: {}, arguments: {:?}",
self.bootstrap_method_ref, self.arguments
)
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_to_string() {
let bootstrap_method = BootstrapMethod {
bootstrap_method_ref: 3,
arguments: vec![42],
};
assert_eq!(
"bootstrap_method_ref: 3, arguments: [42]",
bootstrap_method.to_string()
);
}
#[test]
fn test_serialization() -> Result<()> {
let bootstrap_method = BootstrapMethod {
bootstrap_method_ref: 3,
arguments: vec![42],
};
let expected_value = [0, 3, 0, 1, 0, 42];
let mut bytes = Vec::new();
bootstrap_method.clone().to_bytes(&mut bytes)?;
assert_eq!(expected_value, &bytes[..]);
let mut bytes = ByteReader::new(&expected_value);
assert_eq!(bootstrap_method, BootstrapMethod::from_bytes(&mut bytes)?);
Ok(())
}
}