use grin_core::ser::{self, Readable, Reader, Writeable, Writer};
use std::convert::TryInto;
pub fn write_optional<O: Writeable, W: Writer>(
writer: &mut W,
o: &Option<O>,
) -> Result<(), ser::Error> {
match &o {
Some(o) => {
writer.write_u8(1)?;
o.write(writer)?;
}
None => writer.write_u8(0)?,
};
Ok(())
}
pub fn read_optional<O: Readable, R: Reader>(reader: &mut R) -> Result<Option<O>, ser::Error> {
let o = if reader.read_u8()? == 0 {
None
} else {
Some(O::read(reader)?)
};
Ok(o)
}
pub fn vec_to_array<const S: usize>(vec: &Vec<u8>) -> Result<[u8; S], ser::Error> {
if vec.len() < S {
return Err(ser::Error::CountError);
}
let arr: [u8; S] = vec[0..S].try_into().unwrap();
Ok(arr)
}
#[cfg(test)]
mod tests {
use super::*;
use grin_core::ser::{BinReader, BinWriter, DeserializationMode, ProtocolVersion};
#[test]
fn test_write_optional() {
let mut buf: Vec<u8> = vec![];
let val: Option<u32> = Some(10);
write_optional(&mut BinWriter::default(&mut buf), &val).unwrap();
assert_eq!(buf, &[1, 0, 0, 0, 10]);
buf.clear();
let val: Option<u32> = None;
write_optional(&mut BinWriter::default(&mut buf), &val).unwrap();
assert_eq!(buf, &[0]); }
#[test]
fn test_read_optional() {
let mut buf: &[u8] = &[1, 0, 0, 0, 10]; let val: Option<u32> = read_optional(&mut BinReader::new(
&mut buf,
ProtocolVersion::local(),
DeserializationMode::default(),
))
.unwrap();
assert_eq!(val, Some(10));
buf = &[0]; let val: Option<u32> = read_optional(&mut BinReader::new(
&mut buf,
ProtocolVersion::local(),
DeserializationMode::default(),
))
.unwrap();
assert_eq!(val, None);
}
#[test]
fn test_vec_to_array_success() {
let v = vec![1, 2, 3, 4, 5, 6, 7, 8];
let a = vec_to_array::<4>(&v).unwrap();
assert_eq!(a, [1, 2, 3, 4]);
}
#[test]
fn test_vec_to_array_too_small() {
let v = vec![1, 2, 3];
let res = vec_to_array::<4>(&v);
assert!(res.is_err());
}
#[test]
fn test_vec_to_array_empty() {
let v = vec![];
let res = vec_to_array::<4>(&v);
assert!(res.is_err());
}
}