diff --git a/packed_struct/Cargo.toml b/packed_struct/Cargo.toml index 94f74df..8b68e35 100644 --- a/packed_struct/Cargo.toml +++ b/packed_struct/Cargo.toml @@ -3,7 +3,7 @@ name = "packed_struct" description = "Binary-level structure packing and unpacking generator" repository = "https://github.com/hashmismatch/packed_struct.rs" homepage = "http://www.hashmismatch.net/libraries/packed-struct/" -version = "0.10.1" +version = "0.11.0" rust-version = "1.51" authors = ["Rudi Benkovic "] license = "MIT OR Apache-2.0" @@ -13,7 +13,7 @@ readme = "../README.md" edition = "2018" [dependencies] -packed_struct_codegen = { path = "../packed_struct_codegen/", version = "0.10.1" } +packed_struct_codegen = { path = "../packed_struct_codegen/", version = "0.11.0" } serde = { version = "1.0", optional = true, default-features = false } serde_derive = { version = "1.0", optional = true } bitvec = { version = "0.22.3", default-features = false } diff --git a/packed_struct/src/lib.rs b/packed_struct/src/lib.rs index 833a200..6f76e30 100644 --- a/packed_struct/src/lib.rs +++ b/packed_struct/src/lib.rs @@ -272,7 +272,7 @@ //! ```rust //! use packed_struct::prelude::*; //! -//! #[derive(PrimitiveEnum, Clone, Copy, PartialEq, Debug)] +//! #[derive(PrimitiveEnum_u8, Clone, Copy, PartialEq, Debug)] //! pub enum ImplicitType { //! VariantMin = 0, //! VariantMax = 255 @@ -377,7 +377,6 @@ pub use self::packing::*; /// The derivation macros for packing and enums. pub mod derive { pub use packed_struct_codegen::PackedStruct; - pub use packed_struct_codegen::PrimitiveEnum; pub use packed_struct_codegen::{PrimitiveEnum_u8, PrimitiveEnum_u16, PrimitiveEnum_u32, PrimitiveEnum_u64}; pub use packed_struct_codegen::{PrimitiveEnum_i8, PrimitiveEnum_i16, PrimitiveEnum_i32, PrimitiveEnum_i64}; } diff --git a/packed_struct_codegen/Cargo.toml b/packed_struct_codegen/Cargo.toml index 77ede43..0e53e67 100644 --- a/packed_struct_codegen/Cargo.toml +++ b/packed_struct_codegen/Cargo.toml @@ -2,7 +2,7 @@ name = "packed_struct_codegen" description = "This crate implements the code generation for the packed_struct library." repository = "https://github.com/hashmismatch/packed_struct.rs" -version = "0.10.1" +version = "0.11.0" license = "MIT OR Apache-2.0" authors = ["Rudi Benkovic "] edition = "2018" diff --git a/packed_struct_codegen/src/lib.rs b/packed_struct_codegen/src/lib.rs index 3c6b1ce..cec678f 100644 --- a/packed_struct_codegen/src/lib.rs +++ b/packed_struct_codegen/src/lib.rs @@ -36,55 +36,48 @@ pub fn derive_packable_bytes(tokens: TokenStream) -> TokenStream { .into() } -/// A derive macro that generates packing and unpacking code for simple enum variants. -/// It helps with converting your enums into integer types and back, with many other helper -/// traits. -#[proc_macro_derive(PrimitiveEnum)] -pub fn derive_primitive_detect(input: TokenStream) -> TokenStream { - derive_primitive(input, None) -} #[proc_macro_derive(PrimitiveEnum_u8)] pub fn derive_primitive_u8(input: TokenStream) -> TokenStream { - derive_primitive(input, Some(syn::parse_str::("u8").unwrap())) + derive_primitive(input, syn::parse_str::("u8").unwrap()) } #[proc_macro_derive(PrimitiveEnum_u16)] pub fn derive_primitive_u16(input: TokenStream) -> TokenStream { - derive_primitive(input, Some(syn::parse_str::("u16").unwrap())) + derive_primitive(input, syn::parse_str::("u16").unwrap()) } #[proc_macro_derive(PrimitiveEnum_u32)] pub fn derive_primitive_u32(input: TokenStream) -> TokenStream { - derive_primitive(input, Some(syn::parse_str::("u32").unwrap())) + derive_primitive(input, syn::parse_str::("u32").unwrap()) } #[proc_macro_derive(PrimitiveEnum_u64)] pub fn derive_primitive_u64(input: TokenStream) -> TokenStream { - derive_primitive(input, Some(syn::parse_str::("u64").unwrap())) + derive_primitive(input, syn::parse_str::("u64").unwrap()) } #[proc_macro_derive(PrimitiveEnum_i8)] pub fn derive_primitive_i8(input: TokenStream) -> TokenStream { - derive_primitive(input, Some(syn::parse_str::("i8").unwrap())) + derive_primitive(input, syn::parse_str::("i8").unwrap()) } #[proc_macro_derive(PrimitiveEnum_i16)] pub fn derive_primitive_i16(input: TokenStream) -> TokenStream { - derive_primitive(input, Some(syn::parse_str::("i16").unwrap())) + derive_primitive(input, syn::parse_str::("i16").unwrap()) } #[proc_macro_derive(PrimitiveEnum_i32)] pub fn derive_primitive_i32(input: TokenStream) -> TokenStream { - derive_primitive(input, Some(syn::parse_str::("i32").unwrap())) + derive_primitive(input, syn::parse_str::("i32").unwrap()) } #[proc_macro_derive(PrimitiveEnum_i64)] pub fn derive_primitive_i64(input: TokenStream) -> TokenStream { - derive_primitive(input, Some(syn::parse_str::("i64").unwrap())) + derive_primitive(input, syn::parse_str::("i64").unwrap()) } -fn derive_primitive(input: TokenStream, ty: Option) -> TokenStream { +fn derive_primitive(input: TokenStream, ty: syn::Type) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); primitive_enum::derive(&input, ty) diff --git a/packed_struct_codegen/src/pack.rs b/packed_struct_codegen/src/pack.rs index 0cd549e..2129b56 100644 --- a/packed_struct_codegen/src/pack.rs +++ b/packed_struct_codegen/src/pack.rs @@ -13,7 +13,7 @@ pub struct FieldMidPositioning { pub enum FieldKind { Regular { ident: syn::Ident, - field: FieldRegular + field: Box }, Array { ident: syn::Ident, diff --git a/packed_struct_codegen/src/pack_codegen_docs.rs b/packed_struct_codegen/src/pack_codegen_docs.rs index 5c8b46b..1deb17b 100644 --- a/packed_struct_codegen/src/pack_codegen_docs.rs +++ b/packed_struct_codegen/src/pack_codegen_docs.rs @@ -35,7 +35,7 @@ pub fn struct_runtime_formatter(parsed: &PackStruct) -> syn::Result { for (i, field) in elements.iter().enumerate() { - let name_str = format!("{}[{}]", ident.to_string(), i); + let name_str = format!("{}[{}]", ident, i); let bits: syn::ExprRange = syn::parse_str(&format!("{}..{}", field.bit_range.start, field.bit_range.end))?; debug_fields.push(quote! { @@ -136,7 +136,7 @@ pub fn type_docs(parsed: &PackStruct) -> proc_macro2::TokenStream { }, FieldKind::Array { ref ident, ref elements, .. } => { for (i, field) in elements.iter().enumerate() { - emit_field_docs(&field.bit_range, format!("{}[{}]", ident.to_string(), i), &field.ty); + emit_field_docs(&field.bit_range, format!("{}[{}]", ident, i), &field.ty); } } } diff --git a/packed_struct_codegen/src/pack_parse.rs b/packed_struct_codegen/src/pack_parse.rs index 7b65891..eb211b6 100644 --- a/packed_struct_codegen/src/pack_parse.rs +++ b/packed_struct_codegen/src/pack_parse.rs @@ -205,7 +205,7 @@ fn parse_field(field: &syn::Field, mp: &FieldMidPositioning, bit_range: &Range { return Ok( FieldKind::Regular { - field: parse_reg_field(field, &field.ty, bit_range, default_endianness)?, + field: Box::new(parse_reg_field(field, &field.ty, bit_range, default_endianness)?), ident: field.ident.clone().ok_or_else(|| syn::Error::new(field.span(), "Missing ident!"))? } ); @@ -468,7 +468,7 @@ pub fn parse_struct(ast: &syn::DeriveInput) -> syn::Result { }, FieldKind::Array { ref ident, ref elements, .. } => { for (i, field) in elements.iter().enumerate() { - find_overlaps(format!("{}[{}]", ident.to_string(), i), &field.bit_range)?; + find_overlaps(format!("{}[{}]", ident, i), &field.bit_range)?; } } } diff --git a/packed_struct_codegen/src/pack_parse_attributes.rs b/packed_struct_codegen/src/pack_parse_attributes.rs index b2ae419..28a545c 100644 --- a/packed_struct_codegen/src/pack_parse_attributes.rs +++ b/packed_struct_codegen/src/pack_parse_attributes.rs @@ -187,7 +187,7 @@ pub fn parse_position_val(v: &str, multiplier: usize) -> Result::min_value() as i64 { - "i32".into() - } else if n < ::min_value() as i64 { - "i16".into() - } else { - "i8".into() - } - } - } else { - let n = d.discriminant as u64; - if n > ::max_value() as u64 { - "u64".into() - } else if n > ::max_value() as u64 { - "u32".into() - } else if n > ::max_value() as u64 { - "u16".into() - } else { - "u8".into() - } - } - }).collect(); - - // first mention, higher priority - let priority = [ - "i64", - "i32", - "i16", - "i8", - "u64", - "u32", - "u16", - "u8" - ]; - - let mut ty = "u8".to_string(); - for t in min_ty { - if priority.iter().position(|&x| x == t).unwrap() < priority.iter().position(|&x| x == ty).unwrap() { - ty = t; - } - } - - prim_type = Some(syn::parse_str(&ty).expect("int ty parsing failed")); - } - - let prim_type = prim_type.expect("Unable to detect the primitive type for this enum."); - let all_variants_const_ident = syn::Ident::new(&format!("{}_ALL", to_snake_case(&name.to_string())).to_uppercase(), Span::call_site()); - let mut str_format = { let to_display_str = to_display_str.clone(); let all_variants_const_ident = all_variants_const_ident.clone(); @@ -158,10 +102,9 @@ pub fn derive(ast: &syn::DeriveInput, mut prim_type: Option) -> syn:: #[inline] fn from_primitive(val: #prim_type) -> Option { - match val { - #(#from_primitive_match),* , - _ => None - } + #(#from_primitive_match)* + + None } #[inline] @@ -192,31 +135,9 @@ pub fn derive(ast: &syn::DeriveInput, mut prim_type: Option) -> syn:: } struct Variant { - variant: syn::Variant, - discriminant: u64, - negative: bool, - suffix: String + variant: syn::Variant } -impl Variant { - fn get_discriminant(&self) -> proc_macro2::TokenStream { - let s = format!("{}{}", - self.discriminant, - self.suffix - ); - let v: syn::LitInt = syn::parse_str(&s).expect("Error mid-parsing for disc value"); - - if self.negative { - quote! { - - #v - } - } else { - quote! { #v } - } - } -} - - fn get_unitary_enum(input: &syn::DeriveInput) -> syn::Result> { let data_enum = if let syn::Data::Enum(data_enum) = &input.data { data_enum @@ -226,9 +147,6 @@ fn get_unitary_enum(input: &syn::DeriveInput) -> syn::Result> { let mut r = Vec::new(); - let mut d: Option = None; - let mut neg = false; - for variant in &data_enum.variants { match variant.fields { @@ -238,51 +156,9 @@ fn get_unitary_enum(input: &syn::DeriveInput) -> syn::Result> { syn::Fields::Unit => {} } - let (discriminant, negative, suffix) = match &variant.discriminant { - Some((_, syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Int(ref lit_int), .. }))) => { - (lit_int.base10_parse()?, false, lit_int.suffix().into()) - }, - Some((_, - syn::Expr::Unary(syn::ExprUnary { - op: syn::UnOp::Neg(_), - expr, - .. - }) - )) => { - - match **expr { - syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Int(ref lit_int), .. }) => { - (lit_int.base10_parse()?, true, lit_int.suffix().into()) - }, - _ => return Err(syn::Error::new(expr.span(), "Unsupported enum const expr (negated)")) - } - } - Some(_) => { - return Err(syn::Error::new(variant.span(), "Unsupported enum const expr")); - }, - None => { - match d { - None => (0, false, "".into()), - Some(d) => { - if neg { - (d-1, d-1 != 0, "".into()) - } else { - (d+1, false, "".into()) - } - } - } - } - }; - r.push(Variant { - variant: variant.clone(), - discriminant, - negative, - suffix + variant: variant.clone() }); - - d = Some(discriminant); - neg = negative; } Ok(r) diff --git a/packed_struct_examples/Cargo.toml b/packed_struct_examples/Cargo.toml index 794e3dc..85e8fa7 100644 --- a/packed_struct_examples/Cargo.toml +++ b/packed_struct_examples/Cargo.toml @@ -6,4 +6,4 @@ publish = false edition = "2018" [dependencies] -packed_struct = { path = "../packed_struct/", version = "0.10", features = ["byte_types_64"] } +packed_struct = { path = "../packed_struct/", version = "0.11", features = ["byte_types_64"] } diff --git a/packed_struct_examples/src/example1.rs b/packed_struct_examples/src/example1.rs index 752d7f4..fc10a06 100644 --- a/packed_struct_examples/src/example1.rs +++ b/packed_struct_examples/src/example1.rs @@ -26,7 +26,7 @@ pub struct ControlRegister { pub sensor_value: i16 } -#[derive(PrimitiveEnum, Debug, Copy, Clone, PartialEq)] +#[derive(PrimitiveEnum_u8, Debug, Copy, Clone, PartialEq)] pub enum PowerMode { /// The sensor is turned off Off = 0, diff --git a/packed_struct_nostd_tests/Cargo.toml b/packed_struct_nostd_tests/Cargo.toml index 3fd6213..fbbec56 100644 --- a/packed_struct_nostd_tests/Cargo.toml +++ b/packed_struct_nostd_tests/Cargo.toml @@ -4,4 +4,4 @@ version = "0.1.0" authors = ["Rudi Benkovic "] [dependencies] -packed_struct = { path = "../packed_struct/", version = "0.10", default-features = false } \ No newline at end of file +packed_struct = { path = "../packed_struct/", version = "0.11", default-features = false } \ No newline at end of file diff --git a/packed_struct_nostd_tests/src/lib.rs b/packed_struct_nostd_tests/src/lib.rs index 780a670..b1d35ba 100644 --- a/packed_struct_nostd_tests/src/lib.rs +++ b/packed_struct_nostd_tests/src/lib.rs @@ -29,7 +29,7 @@ pub struct ControlRegister { pub sensor_value: i16 } -#[derive(PrimitiveEnum, Debug, Copy, Clone, PartialEq)] +#[derive(PrimitiveEnum_u8, Debug, Copy, Clone, PartialEq)] pub enum PowerMode { /// The sensor is turned off Off = 0, diff --git a/packed_struct_tests/Cargo.toml b/packed_struct_tests/Cargo.toml index 7e37f6f..d99a187 100644 --- a/packed_struct_tests/Cargo.toml +++ b/packed_struct_tests/Cargo.toml @@ -6,6 +6,6 @@ publish = false edition = "2018" [dependencies] -packed_struct = { path = "../packed_struct/", version = "0.10", features = ["byte_types_64", "use_serde"] } +packed_struct = { path = "../packed_struct/", version = "0.11", features = ["byte_types_64", "use_serde"] } error-chain = "0.12.0" serde = "1.0" \ No newline at end of file diff --git a/packed_struct_tests/tests/primitive_enum_consts.rs b/packed_struct_tests/tests/primitive_enum_consts.rs new file mode 100644 index 0000000..34a6dc4 --- /dev/null +++ b/packed_struct_tests/tests/primitive_enum_consts.rs @@ -0,0 +1,31 @@ +use packed_struct::prelude::*; + +pub const A1: u16 = 0; +pub const A2: u16 = 1; +pub const B1: u16 = 100; +pub const C1: u16 = 200; + +#[derive(PrimitiveEnum_u16, Clone, Copy, Debug, PartialEq)] +#[repr(u16)] +pub enum ConstEnum { + A1 = A1, + A2 = A2, + B1 = B1, + B2, + C1 = C1, + C2, + D1 = 300, + D2 +} + +#[test] +fn prim() { + assert_eq!(0, ConstEnum::A1.to_primitive()); + assert_eq!(1, ConstEnum::A2.to_primitive()); + assert_eq!(100, ConstEnum::B1.to_primitive()); + assert_eq!(101, ConstEnum::B2.to_primitive()); + assert_eq!(200, ConstEnum::C1.to_primitive()); + assert_eq!(201, ConstEnum::C2.to_primitive()); + assert_eq!(300, ConstEnum::D1.to_primitive()); + assert_eq!(301, ConstEnum::D2.to_primitive()); +} \ No newline at end of file diff --git a/packed_struct_tests/tests/primitive_enum_types.rs b/packed_struct_tests/tests/primitive_enum_types.rs index 630bd74..a829746 100644 --- a/packed_struct_tests/tests/primitive_enum_types.rs +++ b/packed_struct_tests/tests/primitive_enum_types.rs @@ -1,52 +1,52 @@ #![allow(clippy::enum_clike_unportable_variant)] use packed_struct::prelude::*; -#[derive(PrimitiveEnum, PartialEq, Debug, Clone, Copy)] +#[derive(PrimitiveEnum_u8, PartialEq, Debug, Clone, Copy)] pub enum EnumU8 { VariantMin = 0, VariantMax = 255 } -#[derive(PrimitiveEnum, PartialEq, Debug, Clone, Copy)] +#[derive(PrimitiveEnum_u16, PartialEq, Debug, Clone, Copy)] pub enum EnumU16 { VariantMin = 0, VariantMax = 65535 } #[repr(u32)] -#[derive(PrimitiveEnum, PartialEq, Debug, Clone, Copy)] +#[derive(PrimitiveEnum_u32, PartialEq, Debug, Clone, Copy)] pub enum EnumU32 { VariantMin = 0, VariantMax = 4294967295 } #[cfg(target_pointer_width = "64")] -#[derive(PrimitiveEnum, PartialEq, Debug, Clone, Copy)] +#[derive(PrimitiveEnum_u64, PartialEq, Debug, Clone, Copy)] pub enum EnumU64 { VariantMin = 0, VariantMax = 1844674407370955165 } -#[derive(PrimitiveEnum, PartialEq, Debug, Clone, Copy)] +#[derive(PrimitiveEnum_i8, PartialEq, Debug, Clone, Copy)] pub enum EnumI8 { VariantMin = -128, VariantMax = 127 } -#[derive(PrimitiveEnum, PartialEq, Debug, Clone, Copy)] +#[derive(PrimitiveEnum_i16, PartialEq, Debug, Clone, Copy)] pub enum EnumI16 { VariantMin = -32768, VariantMax = 32767 } -#[derive(PrimitiveEnum, PartialEq, Debug, Clone, Copy)] +#[derive(PrimitiveEnum_i32, PartialEq, Debug, Clone, Copy)] pub enum EnumI32 { VariantMin = -2147483648, VariantMax = 2147483647 } #[cfg(target_pointer_width = "64")] -#[derive(PrimitiveEnum, PartialEq, Debug, Clone, Copy)] +#[derive(PrimitiveEnum_i64, PartialEq, Debug, Clone, Copy)] pub enum EnumI64 { VariantMin = -9223372036854775808, VariantMax = 9223372036854775807 diff --git a/packed_struct_tests/tests/primitive_enum_values.rs b/packed_struct_tests/tests/primitive_enum_values.rs index 74232fe..25f765d 100644 --- a/packed_struct_tests/tests/primitive_enum_values.rs +++ b/packed_struct_tests/tests/primitive_enum_values.rs @@ -1,6 +1,6 @@ use packed_struct::prelude::*; -#[derive(PrimitiveEnum, PartialEq, Debug, Clone, Copy)] +#[derive(PrimitiveEnum_i8, PartialEq, Debug, Clone, Copy)] pub enum EnumI8 { VariantMin = -128,