Skip to content

Commit

Permalink
allow broader meta parameters (#10)
Browse files Browse the repository at this point in the history
- allow all meta parameters (i.e., `#[allow(clippy::...)]` additions to structs/enums were accepted
- remove special `#derive[(Default)]` specialization due to macro parsing conflicts with the new addition
  - still very easy to implement `Default` with use of `of_defaults()`
- bump version to `0.3.0` as ^ is a breaking change
  • Loading branch information
Andrew Gazelka authored Nov 8, 2022
1 parent 9cdab5f commit f89514c
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 90 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "bit-struct"
version = "0.2.0"
version = "0.3.0"
edition = "2021"
description = "Define structs which have fields which are assigned to individual bits, not bytes"
repository = "https://github.com/parallel-systems/bit-struct"
Expand Down
121 changes: 42 additions & 79 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
#![no_std]

use core::{
cmp::Ordering,
fmt::{Debug, Display, Formatter},
fmt::{Debug, Display},
marker::PhantomData,
ops::{
Add, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, Mul, Rem, Shl,
Expand All @@ -17,6 +16,7 @@ use num_traits::{Bounded, Num, One, Zero};
pub use serde;

mod types;

pub use types::{
i10, i11, i12, i13, i14, i15, i17, i18, i19, i2, i20, i21, i22, i23, i24, i25, i26, i27, i28,
i29, i3, i30, i31, i33, i34, i35, i36, i37, i38, i39, i4, i40, i41, i42, i43, i44, i45, i46,
Expand All @@ -38,7 +38,7 @@ pub use types::{
/// This makes the macros for the end-user more ergonomic, as they can use the
/// macro multiple times in a single module.
#[repr(transparent)]
#[derive(Copy, Clone, PartialOrd, PartialEq, Eq, Ord, Hash, Default)]
#[derive(Copy, Clone, PartialOrd, PartialEq, Eq, Ord, Hash)]
pub struct UnsafeStorage<T>(T);

impl<T> UnsafeStorage<T> {
Expand Down Expand Up @@ -311,15 +311,13 @@ impl<T: BitStruct<true>> BitStructExt for T {
#[doc(hidden)]
#[macro_export]
macro_rules! impl_fields {

($on: expr, $kind: ty =>
[$($first_field_doc: expr),*], $head_field: ident, $head_actual: ty $(, [$($field_doc: expr),*], $field: ident, $actual: ty)*) => {
$(#[doc=$first_field_doc])*
($on: expr, $kind: ty =>[$($first_field_meta: meta),*], $head_field: ident, $head_actual: ty $(, [$($field_meta: meta),*], $field: ident, $actual: ty)*) => {
$(#[$first_field_meta])*
pub fn $head_field(&mut self) -> $crate::GetSet<'_, $kind, $head_actual, {$on - <$head_actual as $crate::BitCount>::COUNT}, {$on - 1}> {
$crate::GetSet::new(unsafe {self.0.as_ref_mut()})
}

$crate::impl_fields!($on - <$head_actual as $crate::BitCount>::COUNT, $kind => $([$($field_doc),*], $field, $actual),*);
$crate::impl_fields!($on - <$head_actual as $crate::BitCount>::COUNT, $kind => $([$($field_meta),*], $field, $actual),*);
};
($on: expr, $kind: ty =>) => {};
}
Expand All @@ -329,40 +327,10 @@ macro_rules! impl_fields {
#[macro_export]
macro_rules! bit_struct_impl {
(
$(#[doc = $struct_doc:expr])*
#[derive(Default)]
$struct_vis: vis struct $name: ident ($kind: ty) {
$(
$(#[doc = $field_doc:expr])*
$field: ident: $actual: ty
),* $(,)?
}
) => {

$crate::bit_struct_impl!(
$(#[doc = $struct_doc])*
$struct_vis struct $name ($kind) {
$(
$(#[doc = $field_doc])*
$field: $actual
),*
}

);

impl Default for $name {
fn default() -> Self {
Self::of_defaults()
}
}

};

(
$(#[doc = $struct_doc:expr])*
$(#[$meta: meta])*
$struct_vis: vis struct $name: ident ($kind: ty) {
$(
$(#[doc = $field_doc:expr])*
$(#[$field_meta: meta])*
$field: ident: $actual: ty
),* $(,)?
}
Expand Down Expand Up @@ -443,9 +411,7 @@ impl<T: Zero> BitStructZero for T {}
/// }
///
/// bit_struct::bit_struct! {
/// /// We can write documentation for the struct here. Here BitStruct1
/// /// derives default values from the above enums macro
/// #[derive(Default)]
/// /// We can write documentation for the struct here.
/// struct BitStruct1 (u16){
/// /// a 1 bit element. This is stored in u16[15]
/// a: bit_struct::u1,
Expand All @@ -469,7 +435,7 @@ impl<T: Zero> BitStructZero for T {}
///
/// fn main() {
/// use std::convert::TryFrom;
/// let mut bit_struct: BitStruct1 = BitStruct1::default();
/// let mut bit_struct: BitStruct1 = BitStruct1::of_defaults();
///
/// assert_eq!(bit_struct.a().start(), 15);
/// assert_eq!(bit_struct.a().stop(), 15);
Expand Down Expand Up @@ -507,21 +473,21 @@ impl<T: Zero> BitStructZero for T {}
macro_rules! bit_struct {
(
$(
$(#[doc = $struct_doc:expr])*
$(#[derive($($struct_der: ident),+)])?
$(#[$meta:meta])*
$struct_vis: vis struct $name: ident ($kind: ty) {
$(
$(#[doc = $field_doc:expr])*
$(#[$field_meta:meta])*
$field: ident: $actual: ty
),* $(,)?
}
)*
) => {
$(
$(#[doc = $struct_doc])*
$(#[$meta])*
#[derive(Copy, Clone, PartialOrd, PartialEq, Eq, Ord, Hash)]
pub struct $name($crate::UnsafeStorage<$kind>);

#[allow(clippy::used_underscore_binding)]
impl $crate::serde::Serialize for $name {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: $crate::serde::Serializer {

Expand All @@ -539,6 +505,7 @@ macro_rules! bit_struct {
}
}

#[allow(clippy::used_underscore_binding)]
impl $crate::serde::Deserialize<'static> for $name {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: $crate::serde::Deserializer<'static> {

Expand All @@ -555,6 +522,7 @@ macro_rules! bit_struct {
}
}

#[allow(clippy::used_underscore_binding)]
impl TryFrom<$kind> for $name {
type Error = ();
fn try_from(elem: $kind) -> Result<$name, ()> {
Expand All @@ -568,6 +536,7 @@ macro_rules! bit_struct {
}
}

#[allow(clippy::used_underscore_binding)]
impl $crate::BitStruct<{$(<$actual as $crate::ValidCheck<$kind>>::ALWAYS_VALID &&)* true}> for $name {
type Kind = $kind;

Expand All @@ -576,6 +545,7 @@ macro_rules! bit_struct {
}
}

#[allow(clippy::used_underscore_binding)]
impl $name {

unsafe fn from_unchecked(inner: $kind) -> Self {
Expand All @@ -595,18 +565,17 @@ macro_rules! bit_struct {
self.0.inner()
}

$crate::impl_fields!(<$kind as $crate::BitCount>::COUNT, $kind => $([$($field_doc),*], $field, $actual),*);
$crate::impl_fields!(<$kind as $crate::BitCount>::COUNT, $kind => $([$($field_meta),*], $field, $actual),*);
}

)*

$(
$crate::bit_struct_impl!(
$(#[doc = $struct_doc])*
$(#[derive($($struct_der),+)])?
$(#[$meta])*
$struct_vis struct $name ($kind) {
$(
$(#[doc = $field_doc])*
$(#[$field_meta])*
$field: $actual
),*
}
Expand Down Expand Up @@ -718,27 +687,24 @@ macro_rules! enum_impl {

};
(
$(#[doc = $struct_doc:expr])*
$(#[derive($($struct_der:ident),+)])?
$enum_vis: vis $name: ident($default: ident){
$(#[doc = $fst_field_doc:expr])*
$(#[$meta:meta])*
$enum_vis: vis $name: ident($default: ident) {
$(#[$fst_field_meta:meta])*
$fst_field: ident
$(,
$(#[doc = $field_doc:expr])*
$(#[$field_meta:meta])*
$field: ident
)* $(,)?
}
) => {

#[repr(u8)]
$(#[doc = $struct_doc])*
$(#[derive($($struct_der),+)])?
$(#[$meta])*
#[derive(Copy, Clone, Debug, PartialOrd, PartialEq, Eq, $crate::serde::Serialize, $crate::serde::Deserialize)]
$enum_vis enum $name {
$(#[doc = $fst_field_doc])*
$(#[$fst_field_meta])*
$fst_field,
$(
$(#[doc = $field_doc])*
$(#[$field_meta])*
$field
),*
}
Expand Down Expand Up @@ -774,26 +740,24 @@ macro_rules! enum_impl {


(
$(#[doc = $struct_doc:expr])*
$(#[derive($($struct_der:ident),+)])?
$(#[$meta:meta])*
$enum_vis: vis $name: ident {
$(#[doc = $fst_field_doc:expr])*
$(#[$fst_field_meta:meta])*
$fst_field: ident
$(,
$(#[doc = $field_doc:expr])*
$(#[$field_meta:meta])*
$field: ident
)* $(,)?
}
) => {
#[repr(u8)]
$(#[doc = $struct_doc])*
$(#[derive($($struct_der),+)])?
$(#[$meta])*
#[derive(Copy, Clone, Debug, PartialOrd, PartialEq, Eq, $crate::serde::Serialize, $crate::serde::Deserialize)]
$enum_vis enum $name {
$(#[doc = $fst_field_doc])*
$(#[$fst_field_meta])*
$fst_field,
$(
$(#[doc = $field_doc])*
$(#[$field_meta])*
$field
),*
}
Expand Down Expand Up @@ -861,27 +825,26 @@ macro_rules! enum_impl {
macro_rules! enums {
(
$(
$(#[doc = $struct_doc:expr])*
$(#[derive($($struct_der:ident),+)])?
$(#[$meta:meta])*
$enum_vis: vis $name: ident $(($enum_default: ident))? {
$(#[doc = $fst_field_doc:expr])*

$(#[$fst_field_meta:meta])*
$fst_field: ident
$(,
$(#[doc = $field_doc:expr])*
$(#[$field_meta:meta])*
$field: ident
)* $(,)?
}
)+
) => {
$(
$crate::enum_impl!(
$(#[doc = $struct_doc])*
$(#[derive($($struct_der),+)])?
$enum_vis $name $(($enum_default))?{
$(#[doc = $fst_field_doc])*
$(#[$meta])*
$enum_vis $name $(($enum_default))? {
$(#[$fst_field_meta])*
$fst_field
$(,
$(#[doc = $field_doc])*
$(#[$field_meta])*
$field
)*
}
Expand Down
16 changes: 8 additions & 8 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,25 +104,25 @@ macro_rules! new_signed_types {
}

impl PartialOrd for $name {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
fn partial_cmp(&self, other: &Self) -> Option<::core::cmp::Ordering> {
self.value().partial_cmp(&other.value())
}
}

impl Ord for $name {
fn cmp(&self, other: &Self) -> Ordering {
fn cmp(&self, other: &Self) -> ::core::cmp::Ordering {
self.value().cmp(&other.value())
}
}

impl Debug for $name {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
f.write_fmt(format_args!("{}", self.value()))
}
}

impl Display for $name {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
f.write_fmt(format_args!("{}", self.value()))
}
}
Expand Down Expand Up @@ -287,7 +287,7 @@ macro_rules! num_traits {
}
}

impl core::str::FromStr for $num {
impl ::core::str::FromStr for $num {
type Err = <Self as Num>::FromStrRadixErr;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Expand Down Expand Up @@ -395,13 +395,13 @@ macro_rules! new_unsigned_types {
always_valid!($name);

impl Debug for $name {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
f.write_fmt(format_args!("{}", self.0))
}
}

impl Display for $name {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
f.write_fmt(format_args!("{}", self.0))
}
}
Expand Down Expand Up @@ -644,7 +644,7 @@ macro_rules! byte_from_impls {
/// The size of byte array equal to this value
const ARR_SIZE: usize = <$kind>::COUNT / 8;
/// The size of byte array equal to the underlying storage for this value
const SUPER_BYTES: usize = core::mem::size_of::<$super_kind>();
const SUPER_BYTES: usize = ::core::mem::size_of::<$super_kind>();
/// Convert from an array of bytes, in big-endian order
pub fn from_be_bytes(bytes: [u8; Self::ARR_SIZE]) -> Self {
let mut res_bytes = [0_u8; Self::SUPER_BYTES];
Expand Down
12 changes: 11 additions & 1 deletion tests/doc_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ bit_struct::enums! {
bit_struct::bit_struct! {
/// We can write documentation for the struct here. Here BitStruct1
/// derives default values from the above enums macro
#[derive(Default)]
struct BitStruct1 (u16){
/// a 1 bit element. This is stored in u16[15]
a: bit_struct::u1,
Expand All @@ -33,9 +32,20 @@ bit_struct::bit_struct! {
}
}

impl Default for BitStruct1 {
fn default() -> Self {
Self::of_defaults()
}
}

#[test]
fn full_test() {
use std::convert::TryFrom;

assert_eq!(Animal::default(), Animal::Cat);
assert_eq!(BitStruct1::of_defaults().animal().get(), Animal::Cat);
assert_eq!(BitStruct1::default().animal().get(), Animal::Cat);

let mut bit_struct: BitStruct1 = BitStruct1::default();

assert_eq!(bit_struct.a().start(), 15);
Expand Down
Loading

0 comments on commit f89514c

Please sign in to comment.