1use crate::error::DomainError;
7use std::borrow::Cow;
9use std::str::FromStr;
10
11paft_core::other_string_code_type!(
12 pub struct OtherExchange for Exchange;
14 type Error = DomainError;
15 parse(input) => Exchange::try_from_str(input);
16 invalid(input) => DomainError::InvalidExchangeValue {
17 value: input.to_string(),
18 };
19);
20
21#[derive(Debug, Clone, PartialEq, Eq, Hash)]
33#[non_exhaustive]
34pub enum Exchange {
35 NASDAQ,
37 NYSE,
39 AMEX,
41 BATS,
43 OTC,
45 LSE,
47 TSE,
49 HKEX,
51 SSE,
53 SZSE,
55 TSX,
57 ASX,
59 Euronext,
61 XETRA,
63 SIX,
65 BIT,
67 BME,
69 AEX,
71 BRU,
73 LIS,
75 EPA,
77 OSL,
79 STO,
81 CPH,
83 WSE,
85 #[allow(non_camel_case_types)]
87 PSE_CZ,
88 #[allow(non_camel_case_types)]
90 BSE_HU,
91 MOEX,
93 BIST,
95 JSE,
97 TASE,
99 BSE,
101 NSE,
103 KRX,
105 SGX,
107 SET,
109 KLSE,
111 PSE,
113 IDX,
115 HOSE,
117 Other(OtherExchange),
119}
120
121impl Exchange {
122 #[cfg_attr(feature = "tracing", tracing::instrument(level = "debug", err))]
128 pub fn try_from_str(input: &str) -> Result<Self, DomainError> {
129 let trimmed = input.trim();
130 if trimmed.is_empty() {
131 return Err(DomainError::InvalidExchangeValue {
132 value: input.to_string(),
133 });
134 }
135
136 Self::from_str(trimmed).map_err(|_| DomainError::InvalidExchangeValue {
137 value: input.to_string(),
138 })
139 }
140
141 pub fn other(input: &str) -> Result<Self, DomainError> {
148 OtherExchange::new(input).map(Self::Other)
149 }
150
151 #[must_use]
153 pub const fn is_us_exchange(&self) -> bool {
154 matches!(
155 self,
156 Self::NASDAQ | Self::NYSE | Self::AMEX | Self::BATS | Self::OTC
157 )
158 }
159
160 #[must_use]
162 pub const fn is_european_exchange(&self) -> bool {
163 matches!(
164 self,
165 Self::LSE
166 | Self::Euronext
167 | Self::XETRA
168 | Self::SIX
169 | Self::BIT
170 | Self::BME
171 | Self::AEX
172 | Self::BRU
173 | Self::LIS
174 | Self::EPA
175 | Self::OSL
176 | Self::STO
177 | Self::CPH
178 | Self::WSE
179 | Self::PSE_CZ
180 | Self::BSE_HU
181 )
182 }
183
184 #[must_use]
186 pub fn full_name(&self) -> Cow<'static, str> {
187 match self {
188 Self::NASDAQ => Cow::Borrowed("Nasdaq"),
189 Self::NYSE => Cow::Borrowed("NYSE"),
190 Self::AMEX => Cow::Borrowed("AMEX"),
191 Self::BATS => Cow::Borrowed("BATS"),
192 Self::OTC => Cow::Borrowed("OTC"),
193 Self::LSE => Cow::Borrowed("London Stock Exchange"),
194 Self::TSE => Cow::Borrowed("Tokyo Stock Exchange"),
195 Self::HKEX => Cow::Borrowed("Hong Kong Stock Exchange"),
196 Self::SSE => Cow::Borrowed("Shanghai Stock Exchange"),
197 Self::SZSE => Cow::Borrowed("Shenzhen Stock Exchange"),
198 Self::TSX => Cow::Borrowed("Toronto Stock Exchange"),
199 Self::ASX => Cow::Borrowed("Australian Securities Exchange"),
200 Self::Euronext => Cow::Borrowed("Euronext"),
201 Self::XETRA => Cow::Borrowed("Xetra"),
202 Self::SIX => Cow::Borrowed("Swiss Exchange"),
203 Self::BIT => Cow::Borrowed("Borsa Italiana"),
204 Self::BME => Cow::Borrowed("Bolsa de Madrid"),
205 Self::AEX => Cow::Borrowed("Euronext Amsterdam"),
206 Self::BRU => Cow::Borrowed("Euronext Brussels"),
207 Self::LIS => Cow::Borrowed("Euronext Lisbon"),
208 Self::EPA => Cow::Borrowed("Euronext Paris"),
209 Self::OSL => Cow::Borrowed("Oslo Børs"),
210 Self::STO => Cow::Borrowed("Stockholm Stock Exchange"),
211 Self::CPH => Cow::Borrowed("Copenhagen Stock Exchange"),
212 Self::WSE => Cow::Borrowed("Warsaw Stock Exchange"),
213 Self::PSE_CZ => Cow::Borrowed("Prague Stock Exchange"),
214 Self::BSE_HU => Cow::Borrowed("Budapest Stock Exchange"),
215 Self::MOEX => Cow::Borrowed("Moscow Exchange"),
216 Self::BIST => Cow::Borrowed("Istanbul Stock Exchange"),
217 Self::JSE => Cow::Borrowed("Johannesburg Stock Exchange"),
218 Self::TASE => Cow::Borrowed("Tel Aviv Stock Exchange"),
219 Self::BSE => Cow::Borrowed("Bombay Stock Exchange"),
220 Self::NSE => Cow::Borrowed("National Stock Exchange of India"),
221 Self::KRX => Cow::Borrowed("Korea Exchange"),
222 Self::SGX => Cow::Borrowed("Singapore Exchange"),
223 Self::SET => Cow::Borrowed("Stock Exchange of Thailand"),
224 Self::KLSE => Cow::Borrowed("Bursa Malaysia"),
225 Self::PSE => Cow::Borrowed("Philippine Stock Exchange"),
226 Self::IDX => Cow::Borrowed("Indonesia Stock Exchange"),
227 Self::HOSE => Cow::Borrowed("Ho Chi Minh Stock Exchange"),
228 Self::Other(code) => Cow::Owned(code.as_ref().to_string()),
229 }
230 }
231}
232
233crate::string_enum_with_code!(
235 Exchange, Other(OtherExchange), "Exchange",
236 type Error = DomainError;
237 invalid(input) => DomainError::InvalidExchangeValue {
238 value: input.to_string(),
239 };
240 {
241 "NASDAQ" => Exchange::NASDAQ,
242 "NYSE" => Exchange::NYSE,
243 "AMEX" => Exchange::AMEX,
244 "BATS" => Exchange::BATS,
245 "OTC" => Exchange::OTC,
246 "LSE" => Exchange::LSE,
247 "TSE" => Exchange::TSE,
248 "HKEX" => Exchange::HKEX,
249 "SSE" => Exchange::SSE,
250 "SZSE" => Exchange::SZSE,
251 "TSX" => Exchange::TSX,
252 "ASX" => Exchange::ASX,
253 "EURONEXT" => Exchange::Euronext,
254 "XETRA" => Exchange::XETRA,
255 "SIX" => Exchange::SIX,
256 "BIT" => Exchange::BIT,
257 "BME" => Exchange::BME,
258 "AEX" => Exchange::AEX,
259 "BRU" => Exchange::BRU,
260 "LIS" => Exchange::LIS,
261 "EPA" => Exchange::EPA,
262 "OSL" => Exchange::OSL,
263 "STO" => Exchange::STO,
264 "CPH" => Exchange::CPH,
265 "WSE" => Exchange::WSE,
266 "PSE_CZ" => Exchange::PSE_CZ,
267 "BSE_HU" => Exchange::BSE_HU,
268 "MOEX" => Exchange::MOEX,
269 "BIST" => Exchange::BIST,
270 "JSE" => Exchange::JSE,
271 "TASE" => Exchange::TASE,
272 "BSE" => Exchange::BSE,
273 "NSE" => Exchange::NSE,
274 "KRX" => Exchange::KRX,
275 "SGX" => Exchange::SGX,
276 "SET" => Exchange::SET,
277 "KLSE" => Exchange::KLSE,
278 "PSE" => Exchange::PSE,
279 "IDX" => Exchange::IDX,
280 "HOSE" => Exchange::HOSE
281 },
282 {
283 "EURONEXT_PARIS" => Exchange::EPA,
285 "BOMBAY" => Exchange::BSE,
286 "BSE_INDIA" => Exchange::BSE
287 }
288);
289
290crate::impl_display_via_code!(Exchange);