1use crate::error::DomainError;
7use paft_utils::Canonical;
9use std::str::FromStr;
10
11#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
23#[non_exhaustive]
24pub enum Exchange {
25 #[default]
27 NASDAQ,
28 NYSE,
30 AMEX,
32 BATS,
34 OTC,
36 LSE,
38 TSE,
40 HKEX,
42 SSE,
44 SZSE,
46 TSX,
48 ASX,
50 Euronext,
52 XETRA,
54 SIX,
56 BIT,
58 BME,
60 AEX,
62 BRU,
64 LIS,
66 EPA,
68 OSL,
70 STO,
72 CPH,
74 WSE,
76 #[allow(non_camel_case_types)]
78 PSE_CZ,
79 #[allow(non_camel_case_types)]
81 BSE_HU,
82 MOEX,
84 BIST,
86 JSE,
88 TASE,
90 BSE,
92 NSE,
94 KRX,
96 SGX,
98 SET,
100 KLSE,
102 PSE,
104 IDX,
106 HOSE,
108 Other(Canonical),
110}
111
112impl Exchange {
113 #[cfg_attr(feature = "tracing", tracing::instrument(level = "debug", err))]
119 pub fn try_from_str(input: &str) -> Result<Self, DomainError> {
120 let trimmed = input.trim();
121 if trimmed.is_empty() {
122 return Err(DomainError::InvalidExchangeValue {
123 value: input.to_string(),
124 });
125 }
126
127 Self::from_str(trimmed).map_err(|_| DomainError::InvalidExchangeValue {
128 value: input.to_string(),
129 })
130 }
131
132 #[must_use]
134 pub const fn is_us_exchange(&self) -> bool {
135 matches!(
136 self,
137 Self::NASDAQ | Self::NYSE | Self::AMEX | Self::BATS | Self::OTC
138 )
139 }
140
141 #[must_use]
143 pub const fn is_european_exchange(&self) -> bool {
144 matches!(
145 self,
146 Self::LSE
147 | Self::Euronext
148 | Self::XETRA
149 | Self::SIX
150 | Self::BIT
151 | Self::BME
152 | Self::AEX
153 | Self::BRU
154 | Self::LIS
155 | Self::EPA
156 | Self::OSL
157 | Self::STO
158 | Self::CPH
159 | Self::WSE
160 | Self::PSE_CZ
161 | Self::BSE_HU
162 )
163 }
164
165 #[must_use]
167 pub fn full_name(&self) -> &str {
168 match self {
169 Self::NASDAQ => "Nasdaq",
170 Self::NYSE => "NYSE",
171 Self::AMEX => "AMEX",
172 Self::BATS => "BATS",
173 Self::OTC => "OTC",
174 Self::LSE => "London Stock Exchange",
175 Self::TSE => "Tokyo Stock Exchange",
176 Self::HKEX => "Hong Kong Stock Exchange",
177 Self::SSE => "Shanghai Stock Exchange",
178 Self::SZSE => "Shenzhen Stock Exchange",
179 Self::TSX => "Toronto Stock Exchange",
180 Self::ASX => "Australian Securities Exchange",
181 Self::Euronext => "Euronext",
182 Self::XETRA => "Xetra",
183 Self::SIX => "Swiss Exchange",
184 Self::BIT => "Borsa Italiana",
185 Self::BME => "Bolsa de Madrid",
186 Self::AEX => "Euronext Amsterdam",
187 Self::BRU => "Euronext Brussels",
188 Self::LIS => "Euronext Lisbon",
189 Self::EPA => "Euronext Paris",
190 Self::OSL => "Oslo Børs",
191 Self::STO => "Stockholm Stock Exchange",
192 Self::CPH => "Copenhagen Stock Exchange",
193 Self::WSE => "Warsaw Stock Exchange",
194 Self::PSE_CZ => "Prague Stock Exchange",
195 Self::BSE_HU => "Budapest Stock Exchange",
196 Self::MOEX => "Moscow Exchange",
197 Self::BIST => "Istanbul Stock Exchange",
198 Self::JSE => "Johannesburg Stock Exchange",
199 Self::TASE => "Tel Aviv Stock Exchange",
200 Self::BSE => "Bombay Stock Exchange",
201 Self::NSE => "National Stock Exchange of India",
202 Self::KRX => "Korea Exchange",
203 Self::SGX => "Singapore Exchange",
204 Self::SET => "Stock Exchange of Thailand",
205 Self::KLSE => "Bursa Malaysia",
206 Self::PSE => "Philippine Stock Exchange",
207 Self::IDX => "Indonesia Stock Exchange",
208 Self::HOSE => "Ho Chi Minh Stock Exchange",
209 Self::Other(code) => code.as_ref(),
210 }
211 }
212}
213
214crate::string_enum_with_code!(
216 Exchange, Other, "Exchange",
217 {
218 "NASDAQ" => Exchange::NASDAQ,
219 "NYSE" => Exchange::NYSE,
220 "AMEX" => Exchange::AMEX,
221 "BATS" => Exchange::BATS,
222 "OTC" => Exchange::OTC,
223 "LSE" => Exchange::LSE,
224 "TSE" => Exchange::TSE,
225 "HKEX" => Exchange::HKEX,
226 "SSE" => Exchange::SSE,
227 "SZSE" => Exchange::SZSE,
228 "TSX" => Exchange::TSX,
229 "ASX" => Exchange::ASX,
230 "EURONEXT" => Exchange::Euronext,
231 "XETRA" => Exchange::XETRA,
232 "SIX" => Exchange::SIX,
233 "BIT" => Exchange::BIT,
234 "BME" => Exchange::BME,
235 "AEX" => Exchange::AEX,
236 "BRU" => Exchange::BRU,
237 "LIS" => Exchange::LIS,
238 "EPA" => Exchange::EPA,
239 "OSL" => Exchange::OSL,
240 "STO" => Exchange::STO,
241 "CPH" => Exchange::CPH,
242 "WSE" => Exchange::WSE,
243 "PSE_CZ" => Exchange::PSE_CZ,
244 "BSE_HU" => Exchange::BSE_HU,
245 "MOEX" => Exchange::MOEX,
246 "BIST" => Exchange::BIST,
247 "JSE" => Exchange::JSE,
248 "TASE" => Exchange::TASE,
249 "BSE" => Exchange::BSE,
250 "NSE" => Exchange::NSE,
251 "KRX" => Exchange::KRX,
252 "SGX" => Exchange::SGX,
253 "SET" => Exchange::SET,
254 "KLSE" => Exchange::KLSE,
255 "PSE" => Exchange::PSE,
256 "IDX" => Exchange::IDX,
257 "HOSE" => Exchange::HOSE
258 },
259 {
260 "EURONEXT_PARIS" => Exchange::EPA,
262 "BOMBAY" => Exchange::BSE,
263 "BSE_INDIA" => Exchange::BSE
264 }
265);
266
267crate::impl_display_via_code!(Exchange);