openpql_prelude/
buffer.rs

1use std::io;
2
3use super::{Card, HandN};
4
5pub trait BufferWrite {
6    fn write_to<W: io::Write>(self, w: &mut W) -> io::Result<()>;
7}
8
9// TODO: refactor
10mod hand_n {
11    use super::{BufferWrite, Card, HandN, io};
12
13    const CARD_BITS: usize = 6;
14
15    const fn card_to_bits(card: Card) -> u8 {
16        const N_SUITS: u8 = 4;
17        let r = card.rank as u8;
18        let s = card.suit as u8;
19
20        r * N_SUITS + s
21    }
22
23    fn hand_2_to_bits(hand: HandN<2>) -> u16 {
24        let mut res = 0;
25
26        for (i, &card) in hand.iter().enumerate() {
27            let bits = u16::from(card_to_bits(card));
28            res |= bits << (i * CARD_BITS);
29        }
30
31        res
32    }
33
34    fn hand_n_to_bits<const N: usize>(hand: HandN<N>) -> u32 {
35        assert!(N >= 3 && N <= 5);
36        let mut res = 0;
37
38        for (i, &card) in hand.iter().enumerate() {
39            let bits = u32::from(card_to_bits(card));
40            res |= bits << (i * CARD_BITS);
41        }
42
43        res
44    }
45
46    macro_rules! impl_buf_write_hand {
47        ($kind:ty, $proc:expr) => {
48            impl BufferWrite for $kind {
49                fn write_to<W: io::Write>(self, w: &mut W) -> io::Result<()> {
50                    w.write_all(&$proc(self).to_le_bytes())
51                }
52            }
53        };
54    }
55
56    impl_buf_write_hand!(HandN<2>, hand_2_to_bits);
57    impl_buf_write_hand!(HandN<3>, hand_n_to_bits);
58    impl_buf_write_hand!(HandN<4>, hand_n_to_bits);
59    impl_buf_write_hand!(HandN<5>, hand_n_to_bits);
60}