use std::io::Cursor;
use barse::{wrap, Error, FromByteReader};
fn u8_is_digit(value: u8) -> bool {
value.is_ascii_digit()
}
#[derive(FromByteReader)]
struct Option4U8 {
#[barse(reveal = "first")]
_first: u8,
#[barse(with = "u8_is_digit(*first)")]
slice: Option<[u8; 4]>,
}
#[test]
pub fn option() {
fn parse_seq(seq: &[u8]) -> Result<Option<[u8; 4]>, Error> {
Option4U8::from_byte_reader(Cursor::new(seq)).map(|opt| opt.slice)
}
assert!(parse_seq(b"").is_err());
assert!(parse_seq(b"4").is_err());
assert!(parse_seq(b"7").is_err());
assert!(parse_seq(b"9wow").is_err());
assert!(parse_seq(b"Hello").unwrap().is_none());
assert!(parse_seq(b"There").unwrap().is_none());
assert_eq!(parse_seq(b"2nice").unwrap().as_ref(), Some(b"nice"));
assert_eq!(parse_seq(b"5full").unwrap().as_ref(), Some(b"full"));
assert_eq!(parse_seq(b"7there").unwrap().as_ref(), Some(b"ther"));
}
#[derive(FromByteReader)]
struct VecU8 {
#[barse(from = "u8", reveal = "size")]
_size: usize,
#[barse(with = "wrap::Len(*size)")]
vec: Vec<u8>,
}
#[test]
pub fn vec() {
fn parse_seq(seq: &[u8]) -> Result<Vec<u8>, Error> {
VecU8::from_byte_reader(Cursor::new(seq)).map(|vec| vec.vec)
}
assert!(parse_seq(b"").is_err());
assert!(parse_seq(b"\x05nice").is_err());
assert_eq!(parse_seq(b"\x02Ok").unwrap(), b"Ok");
assert_eq!(parse_seq(b"\x05Hello").unwrap(), b"Hello");
assert_eq!(parse_seq(b"\x00Nice to meet you").unwrap(), b"");
}
#[derive(FromByteReader)]
struct VecOpt2U8 {
#[barse(from = "u8", reveal = "size")]
_size: usize,
#[barse(with = "wrap::Len(*size)", reveal = "status")]
_status: Vec<u8>,
#[barse(with = "(wrap::Iter(status), |b: &u8| *b != b'0')")]
vec: Vec<Option<[u8; 2]>>,
}
#[test]
pub fn vec_option() {
fn parse_seq(seq: &[u8]) -> Result<Vec<Option<[u8; 2]>>, Error> {
VecOpt2U8::from_byte_reader(Cursor::new(seq)).map(|v| v.vec)
}
assert!(parse_seq(b"").is_err());
assert_eq!(
parse_seq(b"\x040101abcd").unwrap(),
vec![
None,
Some((b"ab" as &[u8]).try_into().unwrap()),
None,
Some((b"cd" as &[u8]).try_into().unwrap())
]
);
}
#[derive(FromByteReader)]
struct OptVecU8 {
#[barse(from = "u8", reveal = "size")]
_size: usize,
#[barse(with = "(*size != 0, wrap::Len(*size))")]
vec: Option<Vec<u8>>,
}
#[test]
pub fn option_vec() {
fn parse_seq(seq: &[u8]) -> Result<Option<Vec<u8>>, Error> {
OptVecU8::from_byte_reader(Cursor::new(seq)).map(|v| v.vec)
}
assert!(parse_seq(b"").is_err());
assert_eq!(parse_seq(b"\x00Hello").unwrap(), None);
assert_eq!(
parse_seq(b"\x05There").unwrap(),
Some(Vec::from(b"There" as &[u8]))
);
}
#[derive(FromByteReader)]
#[barse(with = "bool", reveal = "cond")]
struct CarryOpt(#[barse(with = "cond")] Option<u8>);
#[derive(FromByteReader)]
#[barse(with = "String", reveal = "carry")]
struct UseFn(#[barse(with = "wrap::Fn(|| Ok::<_, barse::Error>(carry))")] String);
#[derive(FromByteReader)]
#[barse(with = "String", reveal = "carry")]
struct UseCarry(#[barse(with = "wrap::Value(carry)")] String);
#[derive(FromByteReader)]
struct UseDef(#[barse(with = "wrap::Default")] String);