#![allow(clippy::redundant_pattern_matching)]
use super::*;
use bstr::ByteSlice;
use std::borrow::Cow;
use zerocopy::{Immutable, KnownLayout};
#[test]
fn empty() {
assert!(Parser::new(&[]).is_empty());
assert!(!Parser::new(&[42]).is_empty());
}
#[test]
fn len() {
assert_eq!(Parser::new(&[]).len(), 0);
assert_eq!(Parser::new(&[42]).len(), 1);
}
#[test]
fn ints() {
let bytes = &[
0x12, 0x34, 0x56, 0x78, 0xaa, 0xee, 0x55, 0x33, ];
let mut p = Parser::new(bytes);
assert_eq!(p.len(), 8);
assert_eq!(p.u16().unwrap(), 0x3412);
assert_eq!(p.len(), 6);
assert_eq!(p.u32().unwrap(), 0xeeaa_7856);
assert_eq!(p.len(), 2);
assert_eq!(p.u8().unwrap(), 0x55);
assert_eq!(p.len(), 1);
assert_eq!(p.i8().unwrap(), 0x33);
assert_eq!(p.len(), 0);
assert!(p.is_empty());
let mut p = Parser::new(bytes);
p.u8().unwrap();
assert_eq!(p.u16().unwrap(), 0x5634); assert_eq!(p.u32().unwrap(), 0x55_ee_aa_78);
let mut p = Parser::new(&[1, 2, 3, 4]);
assert_eq!(p.u32().unwrap(), 0x04_03_02_01);
assert!(p.is_empty());
let mut p = Parser::new(&[1, 2, 3, 4]);
assert_eq!(p.type_index().unwrap(), TypeIndex(0x04_03_02_01));
assert!(p.is_empty());
}
#[test]
fn strz() {
assert!(Parser::new(&[]).strz().is_err());
assert!(Parser::new(b"x").strz().is_err());
assert_eq!(
Parser::new(&[b'f', b'o', b'o', 0])
.strz()
.unwrap()
.to_str()
.unwrap(),
"foo"
);
}
#[test]
fn strz_bad_utf8() {
let buf: &[u8] = b"\x80 bad\0second string \xe2\x9c\x85\0";
let mut p = Parser::new(buf);
let bad_raw = p.strz().unwrap();
assert!(bad_raw.to_str().is_err()); assert_eq!(bad_raw as &[u8], &[0x80, b' ', b'b', b'a', b'd']);
let bad_lossy: Cow<str> = bad_raw.to_str_lossy();
assert!(matches!(bad_lossy, Cow::Owned(_)));
assert_eq!(bad_lossy, "\u{fffd} bad");
let good = p.strz().unwrap();
let good_str: &str = good.to_str().unwrap();
assert_eq!(good_str, "second string ✅");
assert!(p.is_empty());
}
#[test]
fn strt() {
let buf = b"\x03abc123";
let mut p = Parser::new(buf);
let s = p.strt().unwrap();
assert_eq!(s, "abc");
assert_eq!(p.into_rest(), b"123");
}
#[test]
fn rest() {
let mut p = Parser::new(&[1, 2, 3, 4, 5]);
assert_eq!(p.u8().unwrap(), 1);
assert_eq!(p.peek_rest(), &[2, 3, 4, 5]);
let rest = p.take_rest();
assert_eq!(rest, &[2, 3, 4, 5]);
assert!(p.is_empty());
}
#[test]
fn into_rest() {
let mut p = Parser::new(&[1, 2, 3, 4, 5]);
assert_eq!(p.u8().unwrap(), 1);
let rest = p.into_rest();
assert_eq!(rest, &[2, 3, 4, 5]);
}
#[test]
fn needs() {
let p = Parser::new(&[10, 20]);
assert!(matches!(p.needs(0), Ok(_)));
assert!(matches!(p.needs(2), Ok(_)));
assert!(matches!(p.needs(3), Err(_)));
}
#[test]
fn skip() {
let mut p = Parser::new(&[1, 2, 3, 4, 5]);
p.skip(2).unwrap();
assert_eq!(p.u16().unwrap(), 0x403);
}
#[derive(IntoBytes, FromBytes, Unaligned, KnownLayout, Immutable, PartialEq, Eq, Debug)]
#[repr(C)]
struct Bar {
b: u8,
a: u8,
r: u8,
}
#[test]
fn get() {
let buf = &[b'b', b'a', b'r', 4, 5];
let mut p = Parser::new(buf);
let bar: &Bar = p.get().unwrap();
assert_eq!(bar.b, b'b');
assert_eq!(bar.a, b'a');
assert_eq!(bar.r, b'r');
assert!(p.get::<Bar>().is_err());
}
#[test]
fn copy() {
let buf = &[b'b', b'a', b'r', 4, 5];
let mut p = Parser::new(buf);
let bar: Bar = p.copy().unwrap();
assert_eq!(bar.b, b'b');
assert_eq!(bar.a, b'a');
assert_eq!(bar.r, b'r');
assert!(p.copy::<Bar>().is_err());
}
#[test]
fn slice() {
let buf = b"ABC123()!zap";
let mut p = Parser::new(buf);
let bars: &[Bar] = p.slice(3).unwrap();
assert_eq!(bars.len(), 3);
assert_eq!(
bars[0],
Bar {
b: b'A',
a: b'B',
r: b'C'
}
);
assert_eq!(
bars[1],
Bar {
b: b'1',
a: b'2',
r: b'3'
}
);
assert_eq!(
bars[2],
Bar {
b: b'(',
a: b')',
r: b'!'
}
);
assert_eq!(p.into_rest(), b"zap");
}