1use std::fmt;
2
3use currency_iso4217::Currency as IsoCurrency;
4
5use crate::xfs::{value::XfsValue, xfs_struct::XfsMember};
6use crate::{Error, Result};
7
8use super::Exponent;
9
10#[repr(C)]
12#[derive(Clone, Copy, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)]
13pub struct CurrencyCode(IsoCurrency);
14
15impl CurrencyCode {
16 pub const fn new() -> Self {
18 Self(IsoCurrency::new())
19 }
20
21 pub const fn create(val: IsoCurrency) -> Self {
23 Self(val)
24 }
25
26 pub const fn xfs_name() -> &'static str {
28 "currencyCode"
29 }
30}
31
32impl From<&CurrencyCode> for Exponent {
33 fn from(val: &CurrencyCode) -> Self {
34 Self::create(match val.0 {
35 IsoCurrency::AUD
36 | IsoCurrency::CAD
37 | IsoCurrency::CHF
38 | IsoCurrency::EUR
39 | IsoCurrency::GBP
40 | IsoCurrency::USD => -2,
41 IsoCurrency::JPY | IsoCurrency::MXN => -1,
42 IsoCurrency::AMD => 0,
43 _ => 1,
45 })
46 }
47}
48
49impl From<CurrencyCode> for Exponent {
50 fn from(val: CurrencyCode) -> Self {
51 (&val).into()
52 }
53}
54
55impl From<&str> for CurrencyCode {
56 fn from(val: &str) -> Self {
57 Self(val.into())
58 }
59}
60
61impl From<&CurrencyCode> for &'static str {
62 fn from(val: &CurrencyCode) -> Self {
63 val.0.into()
64 }
65}
66
67impl From<CurrencyCode> for &'static str {
68 fn from(val: CurrencyCode) -> Self {
69 (&val).into()
70 }
71}
72
73impl From<&CurrencyCode> for XfsValue {
74 fn from(val: &CurrencyCode) -> Self {
75 Self::new().with_string(<&str>::from(val))
76 }
77}
78
79impl From<CurrencyCode> for XfsValue {
80 fn from(val: CurrencyCode) -> Self {
81 (&val).into()
82 }
83}
84
85impl TryFrom<&XfsValue> for CurrencyCode {
86 type Error = Error;
87
88 fn try_from(val: &XfsValue) -> Result<Self> {
89 Ok(val
90 .string()
91 .ok_or(Error::Xfs(format!(
92 "Expected CurrencyCode XfsValue, have: {val}"
93 )))?
94 .into())
95 }
96}
97
98impl TryFrom<XfsValue> for CurrencyCode {
99 type Error = Error;
100
101 fn try_from(val: XfsValue) -> Result<Self> {
102 (&val).try_into()
103 }
104}
105
106impl From<&CurrencyCode> for XfsMember {
107 fn from(val: &CurrencyCode) -> Self {
108 Self::create(CurrencyCode::xfs_name(), val.into())
109 }
110}
111
112impl From<CurrencyCode> for XfsMember {
113 fn from(val: CurrencyCode) -> Self {
114 (&val).into()
115 }
116}
117
118impl TryFrom<&XfsMember> for CurrencyCode {
119 type Error = Error;
120
121 fn try_from(val: &XfsMember) -> Result<Self> {
122 match (val.name(), val.value().string()) {
123 (n, Some(v)) if n == CurrencyCode::xfs_name() => Ok(v.into()),
124 _ => Err(Error::Xfs(format!(
125 "Expected CurrencyCode XfsMember, have: {val}"
126 ))),
127 }
128 }
129}
130
131impl TryFrom<XfsMember> for CurrencyCode {
132 type Error = Error;
133
134 fn try_from(val: XfsMember) -> Result<Self> {
135 (&val).try_into()
136 }
137}
138
139impl fmt::Display for CurrencyCode {
140 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
141 write!(f, "{}", self.0)
142 }
143}