use tinyklv::dec::binary as decb;
use tinyklv::enc::binary as encb;
use tinyklv::prelude::*;
#[derive(Klv, Debug, Clone, Copy, PartialEq)]
#[klv(
stream = &[u8],
key(dec = decb::u8, enc = encb::u8),
len(dec = decb::u8_as_usize, enc = encb::u8_from_usize),
)]
struct Reading {
#[klv(key = 0x01, dec = decb::u8, enc = *encb::u8)]
channel: u8,
#[klv(key = 0x02, dec = decb::u8, enc = *encb::u8)]
value: u8,
}
#[derive(Klv, Debug, PartialEq)]
#[klv(
stream = &[u8],
sentinel = b"PAR",
key(dec = decb::u8, enc = encb::u8),
len(dec = decb::u8_as_usize, enc = encb::u8_from_usize),
trait_fallback,
allow_unimplemented_encode,
)]
struct Parent {
#[klv(key = 0x0F, dec = decb::u8)]
id: u8,
#[klv(key = 0x10)]
readings: Vec<Reading>,
}
fn parent_bytes(id: u8, readings: &[Reading]) -> Vec<u8> {
let mut inner = Vec::new();
for r in readings {
inner.extend(r.encode_value());
}
let mut body = vec![0x0F, 0x01, id];
body.push(0x10);
body.push(inner.len() as u8);
body.extend(inner);
let mut out = Vec::new();
out.extend_from_slice(b"PAR");
out.push(body.len() as u8);
out.extend(body);
out
}
#[test]
fn parent_with_repeated_readings_decodes() {
let readings = [
Reading {
channel: 1,
value: 10,
},
Reading {
channel: 2,
value: 20,
},
Reading {
channel: 3,
value: 30,
},
];
let bytes = parent_bytes(7, &readings);
let parent = Parent::decode_frame(&mut bytes.as_slice()).unwrap();
assert_eq!(parent.id, 7);
assert_eq!(parent.readings.len(), 1);
assert_eq!(parent.readings[0].channel, 3);
assert_eq!(parent.readings[0].value, 30);
}
#[test]
fn decoder_parent_with_junk_between() {
let a = parent_bytes(
1,
&[Reading {
channel: 0x11,
value: 0x22,
}],
);
let b = parent_bytes(
2,
&[Reading {
channel: 0x33,
value: 0x44,
}],
);
let c = parent_bytes(
3,
&[Reading {
channel: 0x55,
value: 0x66,
}],
);
let mut blob = Vec::new();
blob.extend_from_slice(&[0x00, 0x00, 0xFF, 0xDE, 0xAD]);
blob.extend(a);
blob.extend_from_slice(&[0xFF, 0x00, 0xBE, 0xEF]);
blob.extend(b);
blob.extend_from_slice(&[0x00, 0xCA, 0xFE]);
blob.extend(c);
let mut dec = Parent::decoder();
dec.feed(&blob);
let mut ids = Vec::new();
for r in dec.iter() {
ids.push(r.id);
}
assert_eq!(ids, vec![1, 2, 3]);
}