Robbepop / modular-bitfield

Macro to generate bitfields for structs that allow for modular use of enums.
Apache License 2.0
155 stars 40 forks source link

Is it possible to make a bitfield for an array of derived BitfieldSpecifiers? #60

Closed koenichiwa closed 3 years ago

koenichiwa commented 3 years ago

I'm working on my first rust project, so I hope I'm the one making mistakes.

My current code is as follows

mod data {
    use modular_bitfield::{
        BitfieldSpecifier,
        bitfield,
    };

    #[derive(BitfieldSpecifier)]
    pub enum Color {
        White,
        Black,
    }

    #[derive(BitfieldSpecifier)]
    #[bits=3]
    pub enum Rank { 
        Pawn,                // I'd rather have this as "Pawn(Color)" but that gives me a conversion error?
        Knight,
        Bishop,
        Rook,
        Queen,
        King,
        None,
    }

    #[bitfield]
    pub struct Board {
        state: [[(Rank, Color); 8]; 8] // Here's where the real problem lies
    }
}

As you can see, everything derives BitfieldSpecifier. But I'm getting the following error:

error[E0277]: the trait bound `[[(Rank, Color); 8]; 8]: Specifier` is not satisfied
  --> src/lib.rs:42:9
   |
42 |         state: [[(Rank, Color); 8]; 8]
   |         ^^^^^ the trait `Specifier` is not implemented for `[[(Rank, Color); 8]; 8]`
   |
   = note: required by `BITS`

How do I satisfy this Specifier trait for an array?

Robbepop commented 3 years ago

I think what you really want is this:

mod data {
    use modular_bitfield::{
        BitfieldSpecifier,
        bitfield,
    };

    #[derive(BitfieldSpecifier)]
    #[bits = 1]
    pub enum Color {
        White,
        Black,
    }

    #[derive(BitfieldSpecifier)]
    #[bits = 3]
    pub enum Rank { 
        Pawn,                // I'd rather have this as "Pawn(Color)" but that gives me a conversion error?
        Knight,
        Bishop,
        Rook,
        Queen,
        King,
        None,
    }

    #[bitfield]
    pub struct Cell {
        rank: Rank,
        color: Color,
    }

    pub struct Board {
        state: [[Cell; 8]; 8]
    }
}
Robbepop commented 3 years ago

To utilize the bits and bytes even better you could introduce yet another struct Cellx2 that combines two cells that each take up 4 bits so that both combined take up an entire byte and use this one to power your Board:

    #[bitfield]
    #[bits = 4]
    pub struct Cell {
        rank: Rank,
        color: Color,
    }

    #[bitfield]
    #[bits = 8]
    pub struct Cellx2 {
        cell_1: Cell,
        cell_2: Cell,
    }

    pub struct Board {
        state: [[Cellx2; 4]; 8]
    }
koenichiwa commented 3 years ago

That's a great solution, thanks!