1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use crate::{
    binary::{
        encode_max,
        encode_min,
        FixedBinaryBuf,
    },
    text::ArrayTextBuf,
};

/**
A 32bit decimal number.
*/
#[derive(Clone, Copy)]
pub struct Bitstring32(FixedBinaryBuf<4, i32>);

impl Bitstring32 {
    /**
    Create a decimal from the given buffer.

    The buffer is assumed to be in little-endian byte-order already.
    */
    pub fn from_le_bytes(bytes: [u8; 4]) -> Self {
        Self(FixedBinaryBuf::from(bytes))
    }

    /**
    Get a reference to the underlying bitstring buffer.

    This buffer is always stored in little-endain byte-order, regardless of the endianness
    of the platform.
    */
    pub fn as_le_bytes(&self) -> &[u8; 4] {
        // Even on big-endian platforms we always encode numbers in little-endian order
        self.0.as_ref()
    }

    /**
    Create a decimal with the finite value zero.
    */
    pub fn zero() -> Self {
        Self::from(0u8)
    }

    /**
    Create a decimal with its maximum finite value.
    */
    pub fn max() -> Self {
        let mut buf = FixedBinaryBuf::ZERO;

        encode_max(&mut buf, false);

        Self(buf)
    }

    /**
    Create a decimal with its minimum finite value.
    */
    pub fn min() -> Self {
        let mut buf = FixedBinaryBuf::ZERO;

        encode_max(&mut buf, true);

        Self(buf)
    }

    /**
    Create a decimal with its minimum positive non-zero value.
    */
    pub fn min_positive() -> Self {
        let mut buf = FixedBinaryBuf::ZERO;

        encode_min(&mut buf, false);

        Self(buf)
    }
}

classify!(Bitstring32);

try_s2d!(ArrayTextBuf::<32> => Bitstring32);
d2s!(Bitstring32);

try_f2d!(f32 => from_f32 => Bitstring32);
try_f2d!(f64 => from_f64 => Bitstring32);

try_d2f!(Bitstring32 => to_f32 => f32);
d2f!(Bitstring32 => to_f64 => f64);

i2d!(i8 => from_i8 => Bitstring32);
i2d!(i16 => from_i16 => Bitstring32);
try_i2d!(i32 => from_i32 => Bitstring32);
try_i2d!(i64 => from_i64 => Bitstring32);
try_i2d!(i128 => from_i128 => Bitstring32);

try_d2i!(Bitstring32 => to_i8 => i8);
try_d2i!(Bitstring32 => to_i16 => i16);
try_d2i!(Bitstring32 => to_i32 => i32);
try_d2i!(Bitstring32 => to_i64 => i64);
try_d2i!(Bitstring32 => to_i128 => i128);

i2d!(u8 => from_u8 => Bitstring32);
i2d!(u16 => from_u16 => Bitstring32);
try_i2d!(u32 => from_u32 => Bitstring32);
try_i2d!(u64 => from_u64 => Bitstring32);
try_i2d!(u128 => from_u128 => Bitstring32);

try_d2i!(Bitstring32 => to_u8 => u8);
try_d2i!(Bitstring32 => to_u16 => u16);
try_d2i!(Bitstring32 => to_u32 => u32);
try_d2i!(Bitstring32 => to_u64 => u64);
try_d2i!(Bitstring32 => to_u128 => u128);