1use std::{cmp, fmt};
2
3use crate::{impl_xfs_array, impl_xfs_i4, impl_xfs_struct, Count, Size};
4
5pub const DENOM_ITEM_LEN: usize = 20;
6
7#[repr(C)]
9#[derive(Clone, Copy, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)]
10pub struct Amount(u32);
11
12impl Amount {
13 pub const fn new() -> Self {
15 Self(0)
16 }
17
18 pub const fn create(val: u32) -> Self {
20 Self(val)
21 }
22
23 pub const fn inner(&self) -> u32 {
25 self.0
26 }
27
28 pub fn set_inner(&mut self, val: u32) {
30 self.0 = val;
31 }
32
33 pub fn into_inner(self) -> u32 {
35 self.0
36 }
37}
38
39impl_xfs_i4!(Amount, "amount");
40
41impl fmt::Display for Amount {
42 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43 write!(f, "{}", self.inner())
44 }
45}
46
47#[repr(C)]
49#[derive(Clone, Copy, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)]
50pub struct Cashbox(u32);
51
52impl Cashbox {
53 pub const fn new() -> Self {
55 Self(0)
56 }
57
58 pub const fn create(val: u32) -> Self {
60 Self(val)
61 }
62
63 pub const fn inner(&self) -> u32 {
65 self.0
66 }
67
68 pub fn set_inner(&mut self, val: u32) {
70 self.0 = val;
71 }
72
73 pub fn into_inner(self) -> u32 {
75 self.0
76 }
77}
78
79impl_xfs_i4!(Cashbox, "cashBox");
80
81impl fmt::Display for Cashbox {
82 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83 write!(f, "{}", self.inner())
84 }
85}
86
87#[repr(C)]
89#[derive(Clone, Copy, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)]
90pub struct Unit(u32);
91
92impl Unit {
93 pub const fn new() -> Self {
95 Self(0)
96 }
97
98 pub const fn create(val: u32) -> Self {
100 Self(val)
101 }
102
103 pub const fn inner(&self) -> u32 {
105 self.0
106 }
107
108 pub fn set_inner(&mut self, val: u32) {
110 self.0 = val;
111 }
112
113 pub fn into_inner(self) -> u32 {
115 self.0
116 }
117}
118
119impl_xfs_i4!(Unit, "unit");
120
121impl fmt::Display for Unit {
122 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
123 write!(f, "{}", self.inner())
124 }
125}
126
127#[repr(C)]
129#[derive(Clone, Copy, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)]
130pub struct Denomination {
131 size: Size,
133 amount: Amount,
135 cashbox: Cashbox,
137 items: DenominationItems,
139}
140
141impl Denomination {
142 pub const fn new() -> Self {
144 Self {
145 size: Size::new(),
146 amount: Amount::new(),
147 cashbox: Cashbox::new(),
148 items: DenominationItems::new(),
149 }
150 }
151
152 pub const fn size(&self) -> u32 {
154 self.size.inner()
155 }
156
157 pub fn set_size(&mut self, size: u32) {
159 self.size.set_inner(size);
160 self.items.set_size(size);
161 }
162
163 pub fn with_size(mut self, size: u32) -> Self {
165 self.set_size(size);
166 self
167 }
168
169 pub const fn amount(&self) -> u32 {
171 self.amount.inner()
172 }
173
174 pub fn set_amount(&mut self, amount: u32) {
176 self.amount.set_inner(amount);
177 }
178
179 pub fn with_amount(mut self, amount: u32) -> Self {
181 self.set_amount(amount);
182 self
183 }
184
185 pub const fn cashbox(&self) -> u32 {
187 self.cashbox.inner()
188 }
189
190 pub fn set_cashbox(&mut self, cashbox: u32) {
192 self.cashbox.set_inner(cashbox);
193 }
194
195 pub fn with_cashbox(mut self, cashbox: u32) -> Self {
197 self.set_cashbox(cashbox);
198 self
199 }
200
201 pub fn items(&self) -> &[DenominationItem] {
203 self.items.items()
204 }
205
206 pub(crate) const fn items_raw(&self) -> &DenominationItems {
207 &self.items
208 }
209
210 pub fn items_mut(&mut self) -> &mut [DenominationItem] {
212 self.items.items_mut()
213 }
214
215 pub fn set_items(&mut self, items: &[DenominationItem]) {
217 self.items.set_items(items);
218 self.size.set_inner(self.items.size());
219 }
220
221 pub fn with_items(mut self, items: &[DenominationItem]) -> Self {
223 self.set_items(items);
224 self
225 }
226}
227
228impl fmt::Display for Denomination {
229 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
230 write!(
231 f,
232 r#"{{"size": {}, "amount": {}, "cashbox": {}, "items": {}"#,
233 self.size, self.amount, self.cashbox, self.items
234 )
235 }
236}
237
238impl_xfs_struct!(
239 Denomination,
240 "denomination",
241 [
242 amount: Amount,
243 cashbox: Cashbox,
244 items: DenominationItems
245 ]
246);
247
248#[repr(C)]
250#[derive(Clone, Copy, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)]
251pub struct DenominationItem {
252 unit: Unit,
254 count: Count,
256}
257
258impl DenominationItem {
259 pub const fn new() -> Self {
261 Self {
262 unit: Unit::new(),
263 count: Count::new(),
264 }
265 }
266
267 pub const fn unit(&self) -> u32 {
269 self.unit.inner()
270 }
271
272 pub fn set_unit(&mut self, unit: u32) {
274 self.unit.set_inner(unit);
275 }
276
277 pub fn with_unit(mut self, unit: u32) -> Self {
279 self.set_unit(unit);
280 self
281 }
282
283 pub const fn count(&self) -> u32 {
285 self.count.inner()
286 }
287
288 pub fn set_count(&mut self, count: u32) {
290 self.count.set_inner(count);
291 }
292
293 pub fn with_count(mut self, count: u32) -> Self {
295 self.set_count(count);
296 self
297 }
298}
299
300impl fmt::Display for DenominationItem {
301 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
302 write!(f, r#"{{"unit":{}, "count":{}}}"#, self.unit, self.count)
303 }
304}
305
306impl_xfs_struct!(DenominationItem, "denominationItem", [unit: Unit, count: Count]);
307
308#[repr(C)]
309#[derive(Clone, Copy, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)]
310pub struct DenominationItems {
311 size: Size,
312 items: [DenominationItem; DENOM_ITEM_LEN],
313}
314
315impl DenominationItems {
316 pub const fn new() -> Self {
318 Self {
319 size: Size::new(),
320 items: [DenominationItem::new(); DENOM_ITEM_LEN],
321 }
322 }
323
324 pub const fn create(items: [DenominationItem; DENOM_ITEM_LEN]) -> Self {
326 Self {
327 size: Size::create(DENOM_ITEM_LEN as u32),
328 items,
329 }
330 }
331
332 pub const fn max_size() -> usize {
334 DENOM_ITEM_LEN
335 }
336
337 pub const fn size(&self) -> u32 {
339 self.size.inner()
340 }
341
342 pub fn set_size(&mut self, size: u32) {
344 self.size.set_inner(size);
345 }
346
347 pub fn items(&self) -> &[DenominationItem] {
349 let size = self.size.inner() as usize;
350 if size <= DENOM_ITEM_LEN {
351 self.items[..size].as_ref()
352 } else {
353 self.items.as_ref()
354 }
355 }
356
357 pub fn items_mut(&mut self) -> &mut [DenominationItem] {
359 let size = self.size.inner() as usize;
360 if size <= DENOM_ITEM_LEN {
361 self.items[..size].as_mut()
362 } else {
363 self.items.as_mut()
364 }
365 }
366
367 pub fn set_items(&mut self, items: &[DenominationItem]) {
369 let len = cmp::min(items.len(), DENOM_ITEM_LEN);
370 self.items[..len]
371 .iter_mut()
372 .zip(items[..len].iter())
373 .for_each(|(dst, &src)| {
374 *dst = src;
375 });
376 self.size.set_inner(len as u32);
377 }
378}
379
380impl fmt::Display for DenominationItems {
381 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
382 write!(f, "{{")?;
383 write!(f, r#""size":{}, "#, self.size)?;
384 write!(f, r#""items": ["#)?;
385
386 for (i, item) in self.items.iter().enumerate() {
387 if i != 0 {
388 write!(f, ", ")?;
389 }
390 write!(f, "{item}")?;
391 }
392
393 write!(f, "]}}")
394 }
395}
396
397impl_xfs_array!(DenominationItems, "items");