use crate::abstractions::{Serializable, SerializationError, SerializationInfo};
#[derive(Debug, PartialEq, Eq)]
pub struct SlotRange {
pub from: Option<u16>,
pub to: Option<u16>,
}
impl SlotRange {
pub fn empty() -> Self {
Self {
from: None,
to: None,
}
}
}
impl Serializable for SlotRange {
fn size(&self) -> usize {
let size = if self.from.is_some() { 2 } else { 0 } + if self.to.is_some() { 2 } else { 0 };
size as usize
}
fn get_bytes(&self) -> Vec<u8> {
let mut buff = Vec::new();
if let Some(from) = self.from {
buff.extend_from_slice(&from.to_be_bytes());
if let Some(to) = self.to {
buff.extend_from_slice(&to.to_be_bytes());
}
}
buff
}
fn from_bytes(data: &[u8], _: Option<SerializationInfo>) -> Result<Self, SerializationError>
where
Self: Sized,
{
if data.is_empty() {
Ok(Self {
from: None,
to: None,
})
} else if data.len() % 2 != 0 {
Err(SerializationError::TooFewBytes(1))
} else {
let mut from = [0u8; 2];
from.copy_from_slice(&data[..2]);
let from = Some(u16::from_be_bytes(from));
Ok(Self {
from,
to: if data.len() > 2 {
let mut to = [0u8; 2];
to.copy_from_slice(&data[2..4]);
Some(u16::from_be_bytes(to))
} else {
None
},
})
}
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn can_serialize_0_slots() {
let range = SlotRange::empty();
assert_eq!(Vec::<u8>::new(), range.get_bytes());
}
#[test]
fn can_serialize_1_slot() {
let range = SlotRange {
from: Some(257),
to: None,
};
assert_eq!(vec![1, 1], range.get_bytes());
}
#[test]
fn can_serialize_2_slots() {
let range = SlotRange {
from: Some(258),
to: Some(259),
};
assert_eq!(vec![1, 2, 1, 3], range.get_bytes());
}
#[test]
fn can_parse_0_slots() {
let bytes = &[];
let range = SlotRange::from_bytes(bytes, None).unwrap();
assert_eq!(
SlotRange {
from: None,
to: None
},
range
);
}
#[test]
fn can_parse_1_slot() {
let bytes = &[0, 255];
let range = SlotRange::from_bytes(bytes, None).unwrap();
assert_eq!(
SlotRange {
from: Some(255),
to: None
},
range
);
}
#[test]
fn can_parse_2_slots() {
let bytes = &[255, 255, 255, 254];
let range = SlotRange::from_bytes(bytes, None).unwrap();
assert_eq!(
SlotRange {
from: Some(u16::MAX),
to: Some(u16::MAX - 1)
},
range
);
}
}