#![cfg(all(feature = "derive", feature = "alloc"))]
use std::marker::PhantomData;
use bin_proto::{BitCodec, BitDecode, BitEncode};
use bitstream_io::BigEndian;
#[derive(Debug, BitDecode, BitEncode, PartialEq)]
#[bin_proto(discriminant_type = u8)]
#[bin_proto(ctx = ())]
pub enum Enum<'a, T: BitDecode + BitEncode> {
#[bin_proto(discriminant = 1)]
Variant1 {
a: T,
len: u8,
#[bin_proto(tag = len as usize)]
arr: Vec<u8>,
},
#[bin_proto(discriminant = 2)]
Variant2(u32, bool, PhantomData<&'a T>),
}
#[derive(Debug, BitDecode, BitEncode, PartialEq)]
#[bin_proto(discriminant_type = u8)]
#[bin_proto(bits = 2)]
pub enum Enum2 {
#[bin_proto(discriminant = 3, other)]
CatchAll(u8),
#[bin_proto(discriminant = 1)]
Variant1(u8),
#[bin_proto(discriminant = 2)]
Variant2(u16),
}
#[derive(Debug, BitDecode, BitEncode, PartialEq)]
pub struct EnumContainer {
e: Enum2,
}
#[derive(Debug, BitDecode, BitEncode, PartialEq)]
pub struct TaggedEnumContainer {
#[bin_proto(tag_type = u16, tag_value = ::bin_proto::Discriminable::discriminant(&self.e).unwrap() as u16)]
e: Enum2,
}
#[derive(Debug, BitDecode, BitEncode, PartialEq)]
pub struct BitFieldTaggedEnumContainer {
#[bin_proto(write_value = ::bin_proto::Discriminable::discriminant(&self.e).unwrap())]
#[bin_proto(bits = 3)]
discriminant: u8,
#[bin_proto(tag = discriminant)]
e: Enum2,
}
#[derive(Debug, BitDecode, BitEncode, PartialEq)]
#[repr(u8)]
pub enum Repr {
VariantA = 1,
VariantB = 2,
}
#[test]
fn decode_enum_variant() {
assert_eq!(
(
Enum::Variant1 {
a: 64u8,
len: 2,
arr: vec![1, 2]
},
40
),
Enum::decode_bytes(&[1, 64, 2, 1, 2], BigEndian).unwrap()
);
}
#[test]
fn encode_enum_variant() {
assert_eq!(
Enum::Variant2::<u32>(20, true, PhantomData)
.encode_bytes(BigEndian)
.unwrap(),
vec![2, 0, 0, 0, 20, 1]
);
}
#[test]
fn decode_enum_variant_in_container() {
assert_eq!(
(
EnumContainer {
e: Enum2::Variant1(2)
},
10
),
EnumContainer::decode_bytes(&[64, 128], BigEndian).unwrap()
);
}
#[test]
fn encode_enum_variant_in_container() {
assert_eq!(
EnumContainer {
e: Enum2::Variant2(511)
}
.encode_bytes(BigEndian)
.unwrap(),
vec![128, 127, 192]
);
}
#[test]
fn decode_enum_variant_in_container_tagged() {
assert_eq!(
(
TaggedEnumContainer {
e: Enum2::Variant1(2)
},
24
),
TaggedEnumContainer::decode_bytes(&[0, 1, 2], BigEndian).unwrap()
);
}
#[test]
fn encode_enum_variant_in_container_tagged() {
assert_eq!(
TaggedEnumContainer {
e: Enum2::Variant2(511)
}
.encode_bytes(BigEndian)
.unwrap(),
vec![0, 2, 1, 255,]
);
}
#[test]
fn decode_enum_variant_in_container_tagged_bitfield() {
assert_eq!(
(
BitFieldTaggedEnumContainer {
discriminant: 1,
e: Enum2::Variant1(2)
},
11
),
BitFieldTaggedEnumContainer::decode_bytes(&[32, 64], BigEndian).unwrap()
);
}
#[test]
fn encode_enum_variant_in_container_tagged_bitfield() {
assert_eq!(
BitFieldTaggedEnumContainer {
discriminant: 2,
e: Enum2::Variant2(511)
}
.encode_bytes(BigEndian)
.unwrap(),
vec![64, 63, 224]
);
}
#[test]
fn encode_enum_variant_catch_all() {
assert_eq!(
Enum2::CatchAll(8).encode_bytes(BigEndian).unwrap(),
vec![194, 0]
);
}
#[test]
fn decode_enum_variant_catch_all_discriminant() {
assert_eq!(
(Enum2::CatchAll(8), 10),
Enum2::decode_bytes(&[194, 0], BigEndian).unwrap()
);
}
#[test]
fn decode_enum_variant_catch_all() {
assert_eq!(
(Enum2::CatchAll(8), 10),
Enum2::decode_bytes(&[2, 0], BigEndian).unwrap()
);
}
#[test]
fn decode_enum_repr() {
assert_eq!(
(Repr::VariantA, 8),
Repr::decode_bytes(&[1], BigEndian).unwrap()
);
}
#[test]
fn encode_enum_repr() {
assert_eq!(Repr::VariantB.encode_bytes(BigEndian).unwrap(), vec![2]);
}