use tinyklv::dec::binary as decb;
use tinyklv::enc::binary as encb;
use tinyklv::prelude::*;
#[derive(Klv, Debug, 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::be_u16,
enc = *encb::be_u16,
)]
sensor_id: u16,
#[klv(
key = 0x02,
dec = decb::be_i32,
enc = *encb::be_i32,
)]
value: i32,
}
#[test]
fn vec_decode_value_empty_stream() {
let result = Vec::<Reading>::decode_value(&mut &[][..]).unwrap();
assert!(result.is_empty());
}
#[test]
fn vec_decode_value_single_item() {
let r = Reading {
sensor_id: 1,
value: 2350,
};
let encoded = r.encode_value();
let result = Vec::<Reading>::decode_value(&mut encoded.as_slice()).unwrap();
assert_eq!(result.len(), 1);
assert_eq!(result[0], r);
}
#[test]
fn vec_decode_value_unframed_merge_last_wins() {
let r1 = Reading {
sensor_id: 1,
value: 100,
};
let r2 = Reading {
sensor_id: 2,
value: 200,
};
let mut stream = r1.encode_value();
stream.extend(r2.encode_value());
let result = Vec::<Reading>::decode_value(&mut stream.as_slice()).unwrap();
assert_eq!(
result.len(),
1,
"unframed: one decode_value call consumes all triples"
);
assert_eq!(result[0].sensor_id, 2);
assert_eq!(result[0].value, 200);
}
#[derive(Klv, Debug, PartialEq)]
#[klv(
stream = &[u8],
key(dec = decb::u8, enc = encb::u8),
len(dec = decb::u8_as_usize, enc = encb::u8_from_usize),
)]
struct SingleField {
#[klv(
key = 0x01,
dec = decb::be_u32,
enc = *encb::be_u32,
)]
val: u32,
}
#[test]
fn vec_decode_value_single_key_last_wins() {
let items: Vec<u32> = vec![10, 20, 30, 40, 50];
let stream: Vec<u8> = items
.iter()
.flat_map(|&v| SingleField { val: v }.encode_value())
.collect();
let result = Vec::<SingleField>::decode_value(&mut stream.as_slice()).unwrap();
assert_eq!(result.len(), 1);
assert_eq!(result[0].val, 50);
}
#[derive(Klv, Debug, PartialEq)]
#[klv(
stream = &[u8],
key(dec = decb::u8, enc = encb::u8),
len(dec = decb::u8_as_usize, enc = encb::u8_from_usize),
deny_unknown_keys,
)]
struct MultiKey {
#[klv(
key = 0x01,
dec = decb::u8,
enc = *encb::u8,
)]
a: u8,
#[klv(
key = 0x02,
dec = decb::u8,
enc = *encb::u8,
)]
b: u8,
#[klv(
key = 0x03,
dec = decb::u8,
enc = *encb::u8,
)]
c: u8,
}
#[test]
fn vec_decode_value_roundtrip_single() {
let mk = MultiKey {
a: 10,
b: 20,
c: 30,
};
let encoded = mk.encode_value();
let result = Vec::<MultiKey>::decode_value(&mut encoded.as_slice()).unwrap();
assert_eq!(result.len(), 1);
assert_eq!(result[0], mk);
}
#[test]
fn vec_decode_value_two_multikey_merge() {
let p1 = MultiKey { a: 1, b: 2, c: 3 };
let p2 = MultiKey {
a: 10,
b: 20,
c: 30,
};
let mut stream = p1.encode_value();
stream.extend(p2.encode_value());
let result = Vec::<MultiKey>::decode_value(&mut stream.as_slice()).unwrap();
assert_eq!(result.len(), 1);
assert_eq!(result[0], p2);
}
#[test]
fn vec_decode_value_trailing_junk_yields_empty() {
let mk = MultiKey { a: 1, b: 2, c: 3 };
let mut stream = mk.encode_value();
stream.extend_from_slice(&[0xFF, 0x10]);
let result = Vec::<MultiKey>::decode_value(&mut stream.as_slice()).unwrap();
assert!(
result.is_empty(),
"Vec<T> blanket stops on inner Err; use Decoder<T> for streaming",
);
}
#[test]
fn vec_decode_value_cursor_safe_on_clean_eof() {
let p1 = MultiKey { a: 1, b: 2, c: 3 };
let p2 = MultiKey {
a: 10,
b: 20,
c: 30,
};
let mut stream = p1.encode_value();
stream.extend(p2.encode_value());
let mut cursor: &[u8] = stream.as_slice();
let _ = Vec::<MultiKey>::decode_value(&mut cursor).unwrap();
assert!(
cursor.is_empty(),
"Vec<T> blanket must drain the outer cursor on clean EOF",
);
}