1#[cfg(not(feature = "std"))]
2use alloc::string::String;
3
4use crate::std;
5use std::fmt;
6
7#[repr(u32)]
9#[derive(Clone, Copy, Debug, Default, PartialEq)]
10pub enum Denomination {
11 #[default]
12 Zero = 0,
13 One = 1,
14 Two = 2,
15 Five = 5,
16 Ten = 10,
17 Twenty = 20,
18 Fifty = 50,
19 Hundred = 100,
20 TwoHundred = 200,
21 FiveHundred = 500,
22 Thousand = 1000,
23 TwoThousand = 2000,
24 FiveThousand = 5000,
25 TenThousand = 10_000,
26 TwentyThousand = 20_000,
27 FiftyThousand = 50_000,
28 HundredThousand = 100_000,
29}
30
31impl From<Denomination> for &'static str {
32 fn from(d: Denomination) -> Self {
33 match d {
34 Denomination::Zero => "Zero",
35 Denomination::One => "One",
36 Denomination::Two => "Two",
37 Denomination::Five => "Five",
38 Denomination::Ten => "Ten",
39 Denomination::Twenty => "Twenty",
40 Denomination::Fifty => "Fifty",
41 Denomination::Hundred => "Hundred",
42 Denomination::TwoHundred => "Two hundred",
43 Denomination::FiveHundred => "Five hundred",
44 Denomination::Thousand => "Thousand",
45 Denomination::TwoThousand => "Two thousand",
46 Denomination::FiveThousand => "Five thousand",
47 Denomination::TenThousand => "Ten thousand",
48 Denomination::TwentyThousand => "Twenty thousand",
49 Denomination::FiftyThousand => "Fifty thousand",
50 Denomination::HundredThousand => "Hundred thousand",
51 }
52 }
53}
54
55impl From<&Denomination> for &'static str {
56 fn from(d: &Denomination) -> Self {
57 (*d).into()
58 }
59}
60
61impl fmt::Display for Denomination {
62 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63 write!(f, r#""{}""#, <&str>::from(self))
64 }
65}
66
67impl From<u32> for Denomination {
68 fn from(digit: u32) -> Self {
69 match digit {
70 0 => Self::Zero,
71 1 => Self::One,
72 2 => Self::Two,
73 5 => Self::Five,
74 10 => Self::Ten,
75 20 => Self::Twenty,
76 50 => Self::Fifty,
77 100 => Self::Hundred,
78 200 => Self::TwoHundred,
79 500 => Self::FiveHundred,
80 1000 => Self::Thousand,
81 2000 => Self::TwoThousand,
82 5000 => Self::FiveThousand,
83 10_000 => Self::TenThousand,
84 20_000 => Self::TwentyThousand,
85 50_000 => Self::FiftyThousand,
86 100_000 => Self::HundredThousand,
87 _ => Self::Zero,
88 }
89 }
90}
91
92impl From<Denomination> for u32 {
93 fn from(d: Denomination) -> Self {
94 d as u32
95 }
96}
97
98bitfield! {
99 #[derive(Clone, Copy, Debug, Default, PartialEq)]
101 pub struct StandardDenomination(u8);
102 u8;
103 pub one, set_one: 0;
104 pub two, set_two: 1;
105 pub three, set_three: 2;
106 pub four, set_four: 3;
107 pub five, set_five: 4;
108 pub six, set_six: 5;
109 pub seven, set_seven: 6;
110}
111
112mod bitmask {
113 pub const DENOMINATION: u8 = 0b111_1111;
114}
115
116impl StandardDenomination {
117 pub const fn all() -> Self {
119 Self(bitmask::DENOMINATION)
120 }
121
122 pub const fn none() -> Self {
124 Self(0)
125 }
126
127 pub const fn from_note_value(note_value: u8) -> Self {
129 match note_value {
130 0b000 => Self::none(),
131 0b001..=0b111 => Self(1 << (note_value - 1)),
132 _ => Self::none(),
133 }
134 }
135
136 pub fn set_all(&mut self) {
138 self.0 |= bitmask::DENOMINATION;
139 }
140
141 pub fn set_inverted(&mut self) {
143 self.0 ^= bitmask::DENOMINATION;
144 }
145
146 pub fn invert(&self) -> Self {
148 Self(self.0 ^ bitmask::DENOMINATION)
149 }
150}
151
152fn denom_delimiter(has_denom: bool) -> &'static str {
153 if has_denom {
154 ","
155 } else {
156 ""
157 }
158}
159
160impl fmt::Display for StandardDenomination {
161 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
162 let mut dis = String::new();
163 let mut has_denom = false;
164
165 if self.one() {
166 dis += "Denom1";
167 has_denom = true;
168 }
169 if self.two() {
170 dis = dis + denom_delimiter(has_denom) + "Denom2";
171 has_denom = true;
172 }
173 if self.three() {
174 dis = dis + denom_delimiter(has_denom) + "Denom3";
175 has_denom = true;
176 }
177 if self.four() {
178 dis = dis + denom_delimiter(has_denom) + "Denom4";
179 has_denom = true;
180 }
181 if self.five() {
182 dis = dis + denom_delimiter(has_denom) + "Denom5";
183 has_denom = true;
184 }
185 if self.six() {
186 dis = dis + denom_delimiter(has_denom) + "Denom6";
187 has_denom = true;
188 }
189 if self.seven() {
190 dis = dis + denom_delimiter(has_denom) + "Denom7";
191 has_denom = true;
192 }
193
194 if has_denom {
195 write!(f, r#""{dis}""#)
196 } else {
197 write!(f, r#""None""#)
198 }
199 }
200}
201
202impl From<StandardDenomination> for u8 {
203 fn from(d: StandardDenomination) -> Self {
204 d.0
205 }
206}
207
208impl From<&StandardDenomination> for u8 {
209 fn from(d: &StandardDenomination) -> Self {
210 d.0
211 }
212}
213
214impl From<u8> for StandardDenomination {
215 fn from(b: u8) -> Self {
216 Self(b & bitmask::DENOMINATION)
217 }
218}
219
220impl From<StandardDenominationFlag> for StandardDenomination {
221 fn from(f: StandardDenominationFlag) -> Self {
222 Self(f as u8)
223 }
224}
225
226#[repr(u8)]
228#[derive(Clone, Copy, Debug, Default, PartialEq)]
229pub enum StandardDenominationFlag {
230 Denom1 = 0b000_0001,
231 Denom2 = 0b000_0010,
232 Denom3 = 0b000_0100,
233 Denom4 = 0b000_1000,
234 Denom5 = 0b001_0000,
235 Denom6 = 0b010_0000,
236 Denom7 = 0b100_0000,
237 #[default]
238 Zero = 0b000_0000,
239}
240
241impl StandardDenominationFlag {
242 pub const fn new() -> Self {
244 Self::Zero
245 }
246}
247
248impl From<StandardDenomination> for StandardDenominationFlag {
249 fn from(d: StandardDenomination) -> Self {
250 if d.one() {
252 Self::Denom1
253 } else if d.two() {
254 Self::Denom2
255 } else if d.three() {
256 Self::Denom3
257 } else if d.four() {
258 Self::Denom4
259 } else if d.five() {
260 Self::Denom5
261 } else if d.six() {
262 Self::Denom6
263 } else if d.seven() {
264 Self::Denom7
265 } else {
266 Self::Zero
267 }
268 }
269}