bnr_xfs/currency/
denomination.rs

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/// Represents a denomination amount.
8#[repr(C)]
9#[derive(Clone, Copy, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)]
10pub struct Amount(u32);
11
12impl Amount {
13    /// Creates a new [Amount].
14    pub const fn new() -> Self {
15        Self(0)
16    }
17
18    /// Creates a new [Amount] from the provided parameter.
19    pub const fn create(val: u32) -> Self {
20        Self(val)
21    }
22
23    /// Gets the inner representation of the [Amount].
24    pub const fn inner(&self) -> u32 {
25        self.0
26    }
27
28    /// Gets the inner representation of the [Amount].
29    pub fn set_inner(&mut self, val: u32) {
30        self.0 = val;
31    }
32
33    /// Converts into the inner representation of the [Amount].
34    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/// Represents a denomination cashbox amount.
48#[repr(C)]
49#[derive(Clone, Copy, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)]
50pub struct Cashbox(u32);
51
52impl Cashbox {
53    /// Creates a new [Cashbox].
54    pub const fn new() -> Self {
55        Self(0)
56    }
57
58    /// Creates a new [Cashbox] from the provided parameter.
59    pub const fn create(val: u32) -> Self {
60        Self(val)
61    }
62
63    /// Gets the inner representation of the [Cashbox].
64    pub const fn inner(&self) -> u32 {
65        self.0
66    }
67
68    /// Gets the inner representation of the [Cashbox].
69    pub fn set_inner(&mut self, val: u32) {
70        self.0 = val;
71    }
72
73    /// Converts into the inner representation of the [Cashbox].
74    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/// Represents a denomination unit.
88#[repr(C)]
89#[derive(Clone, Copy, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)]
90pub struct Unit(u32);
91
92impl Unit {
93    /// Creates a new [Unit].
94    pub const fn new() -> Self {
95        Self(0)
96    }
97
98    /// Creates a new [Unit] from the provided parameter.
99    pub const fn create(val: u32) -> Self {
100        Self(val)
101    }
102
103    /// Gets the inner representation of the [Unit].
104    pub const fn inner(&self) -> u32 {
105        self.0
106    }
107
108    /// Gets the inner representation of the [Unit].
109    pub fn set_inner(&mut self, val: u32) {
110        self.0 = val;
111    }
112
113    /// Converts into the inner representation of the [Unit].
114    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/// This structure handles a list of [DenominationItem]s.
128#[repr(C)]
129#[derive(Clone, Copy, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)]
130pub struct Denomination {
131    /// Size of items array.
132    size: Size,
133    /// Amount in MDU
134    amount: Amount,
135    /// Amount the BNR cannot denominate or dispense
136    cashbox: Cashbox,
137    /// The [DenominationItem]s
138    items: DenominationItems,
139}
140
141impl Denomination {
142    /// Creates a new [Denomination].
143    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    /// Gets the size of the [Denomination].
153    pub const fn size(&self) -> u32 {
154        self.size.inner()
155    }
156
157    /// Sets the size of the [Denomination].
158    pub fn set_size(&mut self, size: u32) {
159        self.size.set_inner(size);
160        self.items.set_size(size);
161    }
162
163    /// Builder function that sets the size of the [Denomination].
164    pub fn with_size(mut self, size: u32) -> Self {
165        self.set_size(size);
166        self
167    }
168
169    /// Gets the amount of the [Denomination].
170    pub const fn amount(&self) -> u32 {
171        self.amount.inner()
172    }
173
174    /// Sets the amount of the [Denomination].
175    pub fn set_amount(&mut self, amount: u32) {
176        self.amount.set_inner(amount);
177    }
178
179    /// Builder function that sets the amount of the [Denomination].
180    pub fn with_amount(mut self, amount: u32) -> Self {
181        self.set_amount(amount);
182        self
183    }
184
185    /// Gets the cashbox of the [Denomination].
186    pub const fn cashbox(&self) -> u32 {
187        self.cashbox.inner()
188    }
189
190    /// Sets the cashbox of the [Denomination].
191    pub fn set_cashbox(&mut self, cashbox: u32) {
192        self.cashbox.set_inner(cashbox);
193    }
194
195    /// Builder function that sets the cashbox of the [Denomination].
196    pub fn with_cashbox(mut self, cashbox: u32) -> Self {
197        self.set_cashbox(cashbox);
198        self
199    }
200
201    /// Gets the list of [DenominationItem]s of the [Denomination].
202    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    /// Gets the mutable list of [DenominationItem]s of the [Denomination].
211    pub fn items_mut(&mut self) -> &mut [DenominationItem] {
212        self.items.items_mut()
213    }
214
215    /// Sets the list of [DenominationItem]s of the [Denomination].
216    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    /// Builder function that sets the list of [DenominationItem]s of the [Denomination].
222    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/// This structure describes the number of bills stored to or dispensed from a Logical Cash Unit.
249#[repr(C)]
250#[derive(Clone, Copy, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)]
251pub struct DenominationItem {
252    /// Logical Cash Unit number
253    unit: Unit,
254    /// Bill count
255    count: Count,
256}
257
258impl DenominationItem {
259    /// Creates a new [DenominationItem].
260    pub const fn new() -> Self {
261        Self {
262            unit: Unit::new(),
263            count: Count::new(),
264        }
265    }
266
267    /// Gets the [LogicalCashUnit] number.
268    pub const fn unit(&self) -> u32 {
269        self.unit.inner()
270    }
271
272    /// Sets the [LogicalCashUnit] number.
273    pub fn set_unit(&mut self, unit: u32) {
274        self.unit.set_inner(unit);
275    }
276
277    /// Builder function that sets the [LogicalCashUnit] number.
278    pub fn with_unit(mut self, unit: u32) -> Self {
279        self.set_unit(unit);
280        self
281    }
282
283    /// Gets the count of [DenominationItem] notes.
284    pub const fn count(&self) -> u32 {
285        self.count.inner()
286    }
287
288    /// Sets the count of [DenominationItem] notes.
289    pub fn set_count(&mut self, count: u32) {
290        self.count.set_inner(count);
291    }
292
293    /// Builder function that sets the count of [DenominationItem] notes.
294    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    /// Creates a new [DenominationItems].
317    pub const fn new() -> Self {
318        Self {
319            size: Size::new(),
320            items: [DenominationItem::new(); DENOM_ITEM_LEN],
321        }
322    }
323
324    /// Creates a new [DenominationItems] from the provided parameter.
325    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    /// Gets the max size.
333    pub const fn max_size() -> usize {
334        DENOM_ITEM_LEN
335    }
336
337    /// Gets the size.
338    pub const fn size(&self) -> u32 {
339        self.size.inner()
340    }
341
342    /// Sets the size.
343    pub fn set_size(&mut self, size: u32) {
344        self.size.set_inner(size);
345    }
346
347    /// Gets a reference to the [DenominationItem] list.
348    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    /// Gets a mutable reference to the [DenominationItem] list.
358    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    /// Sets the [DenominationItem] list.
368    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");