#[macro_use]
extern crate amplify;
#[macro_use]
extern crate strict_encoding_derive;
#[macro_use]
extern crate strict_encoding_test;
mod common;
use std::collections::BTreeMap;
use common::{compile_test, Error, Result};
use strict_encoding::{strict_deserialize, StrictDecode};
use strict_encoding_test::test_encoding_roundtrip;
#[test]
#[should_panic]
fn tlv_no_strict() { compile_test("tlv-failures/no_strict"); }
#[test]
#[should_panic]
fn tlv_no_enums() { compile_test("tlv-failures/no_enums"); }
#[test]
#[should_panic]
fn tlv_no_unions() { compile_test("tlv-failures/no_unions"); }
#[test]
#[should_panic]
fn tlv_non_u16_type() { compile_test("tlv-failures/tlv_non_u16_type"); }
#[test]
#[should_panic]
fn tlv_undeclared() { compile_test("tlv-failures/tlv_undeclared"); }
#[test]
#[should_panic]
fn wrong_unknown_type() { compile_test("tlv-failures/wrong_unknown_type"); }
const TLV_U32: u32 = 0xDEADCAFE;
macro_rules! tlv_u32 {
() => {
[
0x01, 0x00, 0xEF, 0xBE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0xFE, 0xCA, 0xAD, 0xDE,
]
};
}
#[test]
fn tlv_optional() -> Result {
#[derive(Clone, PartialEq, Eq, Debug, Default)]
#[derive(NetworkEncode, NetworkDecode)]
#[network_encoding(use_tlv)]
struct Tlv {
fixed: u8,
#[network_encoding(tlv = 0xBEEF)]
tlv: Option<u32>,
}
test_encoding_roundtrip(
&Tlv {
fixed: 0xDD,
tlv: None,
},
&[0xDD],
)?;
test_encoding_roundtrip(
&Tlv {
fixed: 0xDD,
tlv: Some(TLV_U32),
},
vec![0xDD]
.iter()
.chain(&tlv_u32!()[..])
.cloned()
.collect::<Vec<_>>(),
)
.map_err(Error::from)
}
#[test]
fn tlv_newtype() -> Result {
#[derive(Clone, PartialEq, Eq, Debug, Default)]
#[derive(NetworkEncode, NetworkDecode)]
#[network_encoding(use_tlv)]
struct Tlv(#[network_encoding(tlv = 0xBEEF)] Option<u32>);
test_encoding_roundtrip(&Tlv(None), &[])?;
test_encoding_roundtrip(&Tlv(Some(TLV_U32)), tlv_u32!())
.map_err(Error::from)
}
#[test]
fn tlv_default() -> Result {
#[derive(Clone, PartialEq, Eq, Debug, Default)]
#[derive(NetworkEncode, NetworkDecode)]
#[network_encoding(use_tlv)]
struct TlvDefault {
fixed: u8,
#[network_encoding(tlv = 0xBEEF)]
tlv: Vec<u8>,
}
test_encoding_roundtrip(&TlvDefault::default(), &[0x00])?;
test_encoding_roundtrip(
&TlvDefault {
fixed: 0xDD,
tlv: TLV_U32.to_le_bytes().to_vec(),
},
vec![
0xdd, 0x01, 0x00, 0xef, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x04, 0x00, 0xfe, 0xca, 0xad, 0xde, ],
)
.map_err(Error::from)
}
#[test]
fn tlv_ordering() -> Result {
#[derive(Clone, PartialEq, Eq, Debug, Default)]
#[derive(NetworkEncode, NetworkDecode)]
#[network_encoding(use_tlv)]
struct Tlv {
#[network_encoding(tlv = 0xCAFE)]
second: Option<u8>,
#[network_encoding(tlv = 0xBAD)]
first: Option<u8>,
}
let data = [
0x02, 0x00, 0xAD, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xA1, 0xFE, 0xCA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xA2, ];
let _: Tlv = strict_deserialize(&data).unwrap();
test_encoding_roundtrip(&Tlv::default(), &[])?;
test_encoding_roundtrip(
&Tlv {
second: Some(0xA2),
first: Some(0xA1),
},
&data,
)?;
Tlv::strict_deserialize(&[
0x02, 0x00, 0xFE, 0xCA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xA1, 0xAD, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xA1, ])
.expect_err("");
Ok(())
}
#[test]
fn pseudo_tlv() -> Result {
#[derive(Clone, PartialEq, Eq, Debug, Default)]
#[derive(NetworkEncode, NetworkDecode)]
#[network_encoding(use_tlv)]
struct Tlv {
vec: Vec<u8>,
unknown_tlvs: BTreeMap<usize, Box<[u8]>>,
}
let data1 = [0x00, 0x00, 0x00, 0x00];
let data2 = [
0x03, 0x00, 0xB1, 0xB2, 0xB3, 0x00, 0x00, ];
let _: Tlv = strict_deserialize(&data1).unwrap();
let _: Tlv = strict_deserialize(&data2).unwrap();
test_encoding_roundtrip(&Tlv::default(), &data1)?;
test_encoding_roundtrip(
&Tlv {
vec: vec![0xB1, 0xB2, 0xB3],
unknown_tlvs: bmap! {},
},
&data2,
)
.map_err(Error::from)
}
#[test]
fn tlv_collection() -> Result {
#[derive(Clone, PartialEq, Eq, Debug, Default)]
#[derive(NetworkEncode, NetworkDecode)]
#[network_encoding(use_tlv)]
struct Tlv {
#[network_encoding(tlv = 0xCAFE)]
map: BTreeMap<u8, String>,
#[network_encoding(tlv = 0xBAD)]
vec: Vec<u8>,
}
test_encoding_roundtrip(&Tlv::default(), &[])?;
test_encoding_roundtrip(
&Tlv {
map: bmap! { 0xA1u8 => s!("First"), 0xA2u8 => s!("Second") },
vec: vec![0xB1, 0xB2, 0xB3],
},
&[
0x02, 0x00, 0xAD, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0xB1, 0xB2, 0xB3, 0xFE, 0xCA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0xA1, 0x05, 0x00, b'F', b'i', b'r', b's', b't', 0xA2, 0x06, 0x00, b'S', b'e', b'c', b'o', b'n', b'd',
],
)
.map_err(Error::from)
}
#[test]
fn tlv_unknown() -> Result {
use internet2::tlv;
#[derive(Clone, PartialEq, Eq, Debug, Default)]
#[derive(NetworkEncode, NetworkDecode)]
#[network_encoding(use_tlv)]
struct TlvStream {
field: Vec<u8>,
#[network_encoding(tlv = 1)]
tlv_int: Option<u16>,
#[network_encoding(tlv = 2)]
tlv_int2: Option<String>,
#[network_encoding(unknown_tlvs)]
rest_of_tlvs: tlv::Stream,
}
test_encoding_roundtrip(&TlvStream::default(), &[0x00; 2])
.map_err(Error::from)
}