diff --git a/deku-derive/src/lib.rs b/deku-derive/src/lib.rs index 4c346734..c79626fa 100644 --- a/deku-derive/src/lib.rs +++ b/deku-derive/src/lib.rs @@ -25,6 +25,7 @@ enum Id { TokenStream(TokenStream), LitByteStr(syn::LitByteStr), Int(syn::LitInt), + Bool(syn::LitBool), } impl Display for Id { @@ -39,6 +40,7 @@ impl ToTokens for Id { Id::TokenStream(v) => v.to_tokens(tokens), Id::LitByteStr(v) => v.to_tokens(tokens), Id::Int(v) => v.to_tokens(tokens), + Id::Bool(v) => v.to_tokens(tokens), } } } @@ -53,6 +55,7 @@ impl FromMeta for Id { .expect("could not parse token stream"), )), syn::Lit::Int(ref s) => Ok(Id::Int(s.clone())), + syn::Lit::Bool(ref s) => Ok(Id::Bool(s.clone())), syn::Lit::ByteStr(ref s) => Ok(Id::LitByteStr(s.clone())), _ => Err(darling::Error::unexpected_lit_type(value)), }) diff --git a/deku-derive/src/macros/deku_read.rs b/deku-derive/src/macros/deku_read.rs index 130aaf9b..127f4965 100644 --- a/deku-derive/src/macros/deku_read.rs +++ b/deku-derive/src/macros/deku_read.rs @@ -233,6 +233,7 @@ fn emit_enum(input: &DekuData) -> Result { Id::TokenStream(v) => quote! {&#v}.into_token_stream(), Id::LitByteStr(v) => v.into_token_stream(), Id::Int(v) => v.into_token_stream(), + Id::Bool(v) => v.into_token_stream(), } } else if let Some(variant_id_pat) = &variant.id_pat { // If user has supplied an id, then we have an id_pat that and the id variant doesn't @@ -285,6 +286,7 @@ fn emit_enum(input: &DekuData) -> Result { let deref = match variant_id { Id::TokenStream(_) => quote! {}, Id::Int(_) => quote! {}, + Id::Bool(_) => quote! {}, Id::LitByteStr(_) => quote! {*}, }; diff --git a/deku-derive/src/macros/deku_write.rs b/deku-derive/src/macros/deku_write.rs index c0183eef..f3a29ced 100644 --- a/deku-derive/src/macros/deku_write.rs +++ b/deku-derive/src/macros/deku_write.rs @@ -234,6 +234,12 @@ fn emit_enum(input: &DekuData) -> Result { __deku_variant_id.to_writer(__deku_writer, (#id_args))?; } } + Id::Bool(v) => { + quote! { + let mut __deku_variant_id: #id_type = #v; + __deku_variant_id.to_writer(__deku_writer, (#id_args))?; + } + } Id::LitByteStr(v) => { quote! { let mut __deku_variant_id: #id_type = *#v; diff --git a/tests/test_enum.rs b/tests/test_enum.rs index f839487d..9b88088c 100644 --- a/tests/test_enum.rs +++ b/tests/test_enum.rs @@ -233,3 +233,47 @@ fn id_pat_with_id_bits() { assert_eq!(v, IdPatBitsTuple::B((0, 1))); assert_eq!(input, &*v.to_bytes().unwrap()); } + +#[test] +fn test_litbool_as_id() { + use deku::prelude::*; + + #[derive(DekuRead, DekuWrite, Debug, PartialEq, Eq)] + pub struct A { + #[deku(bits = 1)] + bit: bool, + #[deku(ctx = "*bit")] + var: Var, + } + + #[derive(DekuRead, DekuWrite, Debug, PartialEq, Eq)] + #[deku(id = "bit", ctx = "bit: bool")] + pub enum Var { + #[deku(id = false)] + False(#[deku(bits = 15)] u16), + #[deku(id = true)] + True(#[deku(bits = 15)] u16), + } + let input = [0b1000_0000, 0xff]; + let mut cursor = Cursor::new(input); + let (_, v) = A::from_reader((&mut cursor, 0)).unwrap(); + assert_eq!( + v, + A { + bit: true, + var: Var::True(0x7f01), + } + ); + assert_eq!(input, &*v.to_bytes().unwrap()); + let input = [0b0000_0000, 0xff]; + let mut cursor = Cursor::new(input); + let (_, v) = A::from_reader((&mut cursor, 0)).unwrap(); + assert_eq!( + v, + A { + bit: false, + var: Var::False(0x7f01), + } + ); + assert_eq!(input, &*v.to_bytes().unwrap()); +}