1use serde::{Deserialize, Serialize};
2
3pub mod screeners {
5 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
10 pub enum Screener {
11 AggressiveSmallCaps,
14 DayGainers,
16 DayLosers,
18 GrowthTechnologyStocks,
20 MostActives,
22 MostShortedStocks,
24 SmallCapGainers,
26 UndervaluedGrowthStocks,
28 UndervaluedLargeCaps,
30 ConservativeForeignFunds,
33 HighYieldBond,
35 PortfolioAnchors,
37 SolidLargeGrowthFunds,
39 SolidMidcapGrowthFunds,
41 TopMutualFunds,
43 }
44
45 impl Screener {
46 pub fn as_scr_id(&self) -> &'static str {
48 match self {
49 Screener::AggressiveSmallCaps => "aggressive_small_caps",
50 Screener::DayGainers => "day_gainers",
51 Screener::DayLosers => "day_losers",
52 Screener::GrowthTechnologyStocks => "growth_technology_stocks",
53 Screener::MostActives => "most_actives",
54 Screener::MostShortedStocks => "most_shorted_stocks",
55 Screener::SmallCapGainers => "small_cap_gainers",
56 Screener::UndervaluedGrowthStocks => "undervalued_growth_stocks",
57 Screener::UndervaluedLargeCaps => "undervalued_large_caps",
58 Screener::ConservativeForeignFunds => "conservative_foreign_funds",
59 Screener::HighYieldBond => "high_yield_bond",
60 Screener::PortfolioAnchors => "portfolio_anchors",
61 Screener::SolidLargeGrowthFunds => "solid_large_growth_funds",
62 Screener::SolidMidcapGrowthFunds => "solid_midcap_growth_funds",
63 Screener::TopMutualFunds => "top_mutual_funds",
64 }
65 }
66
67 pub fn parse(s: &str) -> Option<Self> {
77 s.parse().ok()
78 }
79
80 pub fn valid_types() -> &'static str {
82 "aggressive-small-caps, day-gainers, day-losers, growth-technology-stocks, \
83 most-actives, most-shorted-stocks, small-cap-gainers, undervalued-growth-stocks, \
84 undervalued-large-caps, conservative-foreign-funds, high-yield-bond, \
85 portfolio-anchors, solid-large-growth-funds, solid-midcap-growth-funds, \
86 top-mutual-funds"
87 }
88
89 pub fn all() -> &'static [Screener] {
91 &[
92 Screener::AggressiveSmallCaps,
93 Screener::DayGainers,
94 Screener::DayLosers,
95 Screener::GrowthTechnologyStocks,
96 Screener::MostActives,
97 Screener::MostShortedStocks,
98 Screener::SmallCapGainers,
99 Screener::UndervaluedGrowthStocks,
100 Screener::UndervaluedLargeCaps,
101 Screener::ConservativeForeignFunds,
102 Screener::HighYieldBond,
103 Screener::PortfolioAnchors,
104 Screener::SolidLargeGrowthFunds,
105 Screener::SolidMidcapGrowthFunds,
106 Screener::TopMutualFunds,
107 ]
108 }
109 }
110
111 impl std::str::FromStr for Screener {
112 type Err = ();
113
114 fn from_str(s: &str) -> Result<Self, Self::Err> {
115 match s.to_lowercase().replace('_', "-").as_str() {
116 "aggressive-small-caps" => Ok(Screener::AggressiveSmallCaps),
117 "day-gainers" | "gainers" => Ok(Screener::DayGainers),
118 "day-losers" | "losers" => Ok(Screener::DayLosers),
119 "growth-technology-stocks" | "growth-tech" => Ok(Screener::GrowthTechnologyStocks),
120 "most-actives" | "actives" => Ok(Screener::MostActives),
121 "most-shorted-stocks" | "most-shorted" => Ok(Screener::MostShortedStocks),
122 "small-cap-gainers" => Ok(Screener::SmallCapGainers),
123 "undervalued-growth-stocks" | "undervalued-growth" => {
124 Ok(Screener::UndervaluedGrowthStocks)
125 }
126 "undervalued-large-caps" | "undervalued-large" => {
127 Ok(Screener::UndervaluedLargeCaps)
128 }
129 "conservative-foreign-funds" => Ok(Screener::ConservativeForeignFunds),
130 "high-yield-bond" => Ok(Screener::HighYieldBond),
131 "portfolio-anchors" => Ok(Screener::PortfolioAnchors),
132 "solid-large-growth-funds" => Ok(Screener::SolidLargeGrowthFunds),
133 "solid-midcap-growth-funds" => Ok(Screener::SolidMidcapGrowthFunds),
134 "top-mutual-funds" => Ok(Screener::TopMutualFunds),
135 _ => Err(()),
136 }
137 }
138 }
139}
140
141pub mod sectors {
145 use serde::{Deserialize, Serialize};
146
147 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
149 #[serde(rename_all = "kebab-case")]
150 pub enum Sector {
151 Technology,
153 FinancialServices,
155 ConsumerCyclical,
157 CommunicationServices,
159 Healthcare,
161 Industrials,
163 ConsumerDefensive,
165 Energy,
167 BasicMaterials,
169 RealEstate,
171 Utilities,
173 }
174
175 impl Sector {
176 pub fn as_api_path(&self) -> &'static str {
178 match self {
179 Sector::Technology => "technology",
180 Sector::FinancialServices => "financial-services",
181 Sector::ConsumerCyclical => "consumer-cyclical",
182 Sector::CommunicationServices => "communication-services",
183 Sector::Healthcare => "healthcare",
184 Sector::Industrials => "industrials",
185 Sector::ConsumerDefensive => "consumer-defensive",
186 Sector::Energy => "energy",
187 Sector::BasicMaterials => "basic-materials",
188 Sector::RealEstate => "real-estate",
189 Sector::Utilities => "utilities",
190 }
191 }
192
193 pub fn display_name(&self) -> &'static str {
195 match self {
196 Sector::Technology => "Technology",
197 Sector::FinancialServices => "Financial Services",
198 Sector::ConsumerCyclical => "Consumer Cyclical",
199 Sector::CommunicationServices => "Communication Services",
200 Sector::Healthcare => "Healthcare",
201 Sector::Industrials => "Industrials",
202 Sector::ConsumerDefensive => "Consumer Defensive",
203 Sector::Energy => "Energy",
204 Sector::BasicMaterials => "Basic Materials",
205 Sector::RealEstate => "Real Estate",
206 Sector::Utilities => "Utilities",
207 }
208 }
209
210 pub fn valid_types() -> &'static str {
212 "technology, financial-services, consumer-cyclical, communication-services, \
213 healthcare, industrials, consumer-defensive, energy, basic-materials, \
214 real-estate, utilities"
215 }
216
217 pub fn all() -> &'static [Sector] {
219 &[
220 Sector::Technology,
221 Sector::FinancialServices,
222 Sector::ConsumerCyclical,
223 Sector::CommunicationServices,
224 Sector::Healthcare,
225 Sector::Industrials,
226 Sector::ConsumerDefensive,
227 Sector::Energy,
228 Sector::BasicMaterials,
229 Sector::RealEstate,
230 Sector::Utilities,
231 ]
232 }
233 }
234
235 impl std::str::FromStr for Sector {
236 type Err = ();
237
238 fn from_str(s: &str) -> Result<Self, Self::Err> {
239 match s.to_lowercase().replace('_', "-").as_str() {
240 "technology" | "tech" => Ok(Sector::Technology),
241 "financial-services" | "financials" | "financial" => Ok(Sector::FinancialServices),
242 "consumer-cyclical" => Ok(Sector::ConsumerCyclical),
243 "communication-services" | "communication" => Ok(Sector::CommunicationServices),
244 "healthcare" | "health" => Ok(Sector::Healthcare),
245 "industrials" | "industrial" => Ok(Sector::Industrials),
246 "consumer-defensive" => Ok(Sector::ConsumerDefensive),
247 "energy" => Ok(Sector::Energy),
248 "basic-materials" | "materials" => Ok(Sector::BasicMaterials),
249 "real-estate" | "realestate" => Ok(Sector::RealEstate),
250 "utilities" | "utility" => Ok(Sector::Utilities),
251 _ => Err(()),
252 }
253 }
254 }
255
256 impl std::fmt::Display for Sector {
257 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
258 write!(f, "{}", self.display_name())
259 }
260 }
261
262 impl From<Sector> for String {
263 fn from(v: Sector) -> Self {
265 v.display_name().to_string()
266 }
267 }
268}
269
270pub mod indices {
272 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
274 pub enum Region {
275 Americas,
277 Europe,
279 AsiaPacific,
281 MiddleEastAfrica,
283 Currencies,
285 }
286
287 impl std::str::FromStr for Region {
288 type Err = ();
289
290 fn from_str(s: &str) -> Result<Self, Self::Err> {
291 match s.to_lowercase().replace(['-', '_'], "").as_str() {
292 "americas" | "america" | "am" => Ok(Region::Americas),
293 "europe" | "eu" => Ok(Region::Europe),
294 "asiapacific" | "asia" | "apac" => Ok(Region::AsiaPacific),
295 "middleeastafrica" | "mea" | "emea" => Ok(Region::MiddleEastAfrica),
296 "currencies" | "currency" | "fx" => Ok(Region::Currencies),
297 _ => Err(()),
298 }
299 }
300 }
301
302 impl Region {
303 pub fn parse(s: &str) -> Option<Self> {
305 s.parse().ok()
306 }
307
308 pub fn symbols(&self) -> &'static [&'static str] {
310 match self {
311 Region::Americas => AMERICAS,
312 Region::Europe => EUROPE,
313 Region::AsiaPacific => ASIA_PACIFIC,
314 Region::MiddleEastAfrica => MIDDLE_EAST_AFRICA,
315 Region::Currencies => CURRENCIES,
316 }
317 }
318
319 pub fn as_str(&self) -> &'static str {
321 match self {
322 Region::Americas => "americas",
323 Region::Europe => "europe",
324 Region::AsiaPacific => "asia-pacific",
325 Region::MiddleEastAfrica => "middle-east-africa",
326 Region::Currencies => "currencies",
327 }
328 }
329
330 pub fn all() -> &'static [Region] {
332 &[
333 Region::Americas,
334 Region::Europe,
335 Region::AsiaPacific,
336 Region::MiddleEastAfrica,
337 Region::Currencies,
338 ]
339 }
340 }
341
342 pub const AMERICAS: &[&str] = &[
344 "^GSPC", "^DJI", "^IXIC", "^NYA", "^XAX", "^RUT", "^VIX", "^GSPTSE", "^BVSP", "^MXX", "^IPSA", "^MERV", ];
357
358 pub const EUROPE: &[&str] = &[
360 "^FTSE", "^GDAXI", "^FCHI", "^STOXX50E", "^N100", "^BFX", "^BUK100P", "MOEX.ME", "^125904-USD-STRD", ];
370
371 pub const ASIA_PACIFIC: &[&str] = &[
373 "^N225", "^HSI", "000001.SS", "^KS11", "^TWII", "^STI", "^AXJO", "^AORD", "^NZ50", "^BSESN", "^JKSE", "^KLSE", ];
386
387 pub const MIDDLE_EAST_AFRICA: &[&str] = &[
389 "^TA125.TA", "^CASE30", "^JN0U.JO", ];
393
394 pub const CURRENCIES: &[&str] = &[
396 "DX-Y.NYB", "^XDB", "^XDE", "^XDN", "^XDA", ];
402
403 pub fn all_symbols() -> Vec<&'static str> {
405 Region::all()
406 .iter()
407 .flat_map(|r| r.symbols().iter().copied())
408 .collect()
409 }
410}
411
412#[allow(missing_docs)]
417pub mod fundamental_types {
418 pub const TOTAL_REVENUE: &str = "TotalRevenue";
422 pub const OPERATING_REVENUE: &str = "OperatingRevenue";
423 pub const COST_OF_REVENUE: &str = "CostOfRevenue";
424 pub const GROSS_PROFIT: &str = "GrossProfit";
425 pub const OPERATING_EXPENSE: &str = "OperatingExpense";
426 pub const SELLING_GENERAL_AND_ADMIN: &str = "SellingGeneralAndAdministration";
427 pub const RESEARCH_AND_DEVELOPMENT: &str = "ResearchAndDevelopment";
428 pub const OPERATING_INCOME: &str = "OperatingIncome";
429 pub const NET_INTEREST_INCOME: &str = "NetInterestIncome";
430 pub const INTEREST_EXPENSE: &str = "InterestExpense";
431 pub const INTEREST_INCOME: &str = "InterestIncome";
432 pub const NET_NON_OPERATING_INTEREST_INCOME_EXPENSE: &str =
433 "NetNonOperatingInterestIncomeExpense";
434 pub const OTHER_INCOME_EXPENSE: &str = "OtherIncomeExpense";
435 pub const PRETAX_INCOME: &str = "PretaxIncome";
436 pub const TAX_PROVISION: &str = "TaxProvision";
437 pub const NET_INCOME_COMMON_STOCKHOLDERS: &str = "NetIncomeCommonStockholders";
438 pub const NET_INCOME: &str = "NetIncome";
439 pub const DILUTED_EPS: &str = "DilutedEPS";
440 pub const BASIC_EPS: &str = "BasicEPS";
441 pub const DILUTED_AVERAGE_SHARES: &str = "DilutedAverageShares";
442 pub const BASIC_AVERAGE_SHARES: &str = "BasicAverageShares";
443 pub const EBIT: &str = "EBIT";
444 pub const EBITDA: &str = "EBITDA";
445 pub const RECONCILED_COST_OF_REVENUE: &str = "ReconciledCostOfRevenue";
446 pub const RECONCILED_DEPRECIATION: &str = "ReconciledDepreciation";
447 pub const NET_INCOME_FROM_CONTINUING_OPERATION_NET_MINORITY_INTEREST: &str =
448 "NetIncomeFromContinuingOperationNetMinorityInterest";
449 pub const NORMALIZED_EBITDA: &str = "NormalizedEBITDA";
450 pub const TOTAL_EXPENSES: &str = "TotalExpenses";
451 pub const TOTAL_OPERATING_INCOME_AS_REPORTED: &str = "TotalOperatingIncomeAsReported";
452
453 pub const TOTAL_ASSETS: &str = "TotalAssets";
457 pub const CURRENT_ASSETS: &str = "CurrentAssets";
458 pub const CASH_CASH_EQUIVALENTS_AND_SHORT_TERM_INVESTMENTS: &str =
459 "CashCashEquivalentsAndShortTermInvestments";
460 pub const CASH_AND_CASH_EQUIVALENTS: &str = "CashAndCashEquivalents";
461 pub const CASH_FINANCIAL: &str = "CashFinancial";
462 pub const RECEIVABLES: &str = "Receivables";
463 pub const ACCOUNTS_RECEIVABLE: &str = "AccountsReceivable";
464 pub const INVENTORY: &str = "Inventory";
465 pub const PREPAID_ASSETS: &str = "PrepaidAssets";
466 pub const OTHER_CURRENT_ASSETS: &str = "OtherCurrentAssets";
467 pub const TOTAL_NON_CURRENT_ASSETS: &str = "TotalNonCurrentAssets";
468 pub const NET_PPE: &str = "NetPPE";
469 pub const GROSS_PPE: &str = "GrossPPE";
470 pub const ACCUMULATED_DEPRECIATION: &str = "AccumulatedDepreciation";
471 pub const GOODWILL: &str = "Goodwill";
472 pub const GOODWILL_AND_OTHER_INTANGIBLE_ASSETS: &str = "GoodwillAndOtherIntangibleAssets";
473 pub const OTHER_INTANGIBLE_ASSETS: &str = "OtherIntangibleAssets";
474 pub const INVESTMENTS_AND_ADVANCES: &str = "InvestmentsAndAdvances";
475 pub const LONG_TERM_EQUITY_INVESTMENT: &str = "LongTermEquityInvestment";
476 pub const OTHER_NON_CURRENT_ASSETS: &str = "OtherNonCurrentAssets";
477 pub const TOTAL_LIABILITIES_NET_MINORITY_INTEREST: &str = "TotalLiabilitiesNetMinorityInterest";
478 pub const CURRENT_LIABILITIES: &str = "CurrentLiabilities";
479 pub const PAYABLES_AND_ACCRUED_EXPENSES: &str = "PayablesAndAccruedExpenses";
480 pub const ACCOUNTS_PAYABLE: &str = "AccountsPayable";
481 pub const CURRENT_DEBT: &str = "CurrentDebt";
482 pub const CURRENT_DEFERRED_REVENUE: &str = "CurrentDeferredRevenue";
483 pub const OTHER_CURRENT_LIABILITIES: &str = "OtherCurrentLiabilities";
484 pub const TOTAL_NON_CURRENT_LIABILITIES_NET_MINORITY_INTEREST: &str =
485 "TotalNonCurrentLiabilitiesNetMinorityInterest";
486 pub const LONG_TERM_DEBT: &str = "LongTermDebt";
487 pub const LONG_TERM_DEBT_AND_CAPITAL_LEASE_OBLIGATION: &str =
488 "LongTermDebtAndCapitalLeaseObligation";
489 pub const NON_CURRENT_DEFERRED_REVENUE: &str = "NonCurrentDeferredRevenue";
490 pub const NON_CURRENT_DEFERRED_TAXES_LIABILITIES: &str = "NonCurrentDeferredTaxesLiabilities";
491 pub const OTHER_NON_CURRENT_LIABILITIES: &str = "OtherNonCurrentLiabilities";
492 pub const STOCKHOLDERS_EQUITY: &str = "StockholdersEquity";
493 pub const COMMON_STOCK_EQUITY: &str = "CommonStockEquity";
494 pub const COMMON_STOCK: &str = "CommonStock";
495 pub const RETAINED_EARNINGS: &str = "RetainedEarnings";
496 pub const ADDITIONAL_PAID_IN_CAPITAL: &str = "AdditionalPaidInCapital";
497 pub const TREASURY_STOCK: &str = "TreasuryStock";
498 pub const TOTAL_EQUITY_GROSS_MINORITY_INTEREST: &str = "TotalEquityGrossMinorityInterest";
499 pub const WORKING_CAPITAL: &str = "WorkingCapital";
500 pub const INVESTED_CAPITAL: &str = "InvestedCapital";
501 pub const TANGIBLE_BOOK_VALUE: &str = "TangibleBookValue";
502 pub const TOTAL_DEBT: &str = "TotalDebt";
503 pub const NET_DEBT: &str = "NetDebt";
504 pub const SHARE_ISSUED: &str = "ShareIssued";
505 pub const ORDINARY_SHARES_NUMBER: &str = "OrdinarySharesNumber";
506
507 pub const OPERATING_CASH_FLOW: &str = "OperatingCashFlow";
511 pub const CASH_FLOW_FROM_CONTINUING_OPERATING_ACTIVITIES: &str =
512 "CashFlowFromContinuingOperatingActivities";
513 pub const NET_INCOME_FROM_CONTINUING_OPERATIONS: &str = "NetIncomeFromContinuingOperations";
514 pub const DEPRECIATION_AND_AMORTIZATION: &str = "DepreciationAndAmortization";
515 pub const DEFERRED_INCOME_TAX: &str = "DeferredIncomeTax";
516 pub const CHANGE_IN_WORKING_CAPITAL: &str = "ChangeInWorkingCapital";
517 pub const CHANGE_IN_RECEIVABLES: &str = "ChangeInReceivables";
518 pub const CHANGES_IN_ACCOUNT_RECEIVABLES: &str = "ChangesInAccountReceivables";
519 pub const CHANGE_IN_INVENTORY: &str = "ChangeInInventory";
520 pub const CHANGE_IN_ACCOUNT_PAYABLE: &str = "ChangeInAccountPayable";
521 pub const CHANGE_IN_OTHER_WORKING_CAPITAL: &str = "ChangeInOtherWorkingCapital";
522 pub const STOCK_BASED_COMPENSATION: &str = "StockBasedCompensation";
523 pub const OTHER_NON_CASH_ITEMS: &str = "OtherNonCashItems";
524 pub const INVESTING_CASH_FLOW: &str = "InvestingCashFlow";
525 pub const CASH_FLOW_FROM_CONTINUING_INVESTING_ACTIVITIES: &str =
526 "CashFlowFromContinuingInvestingActivities";
527 pub const NET_PPE_PURCHASE_AND_SALE: &str = "NetPPEPurchaseAndSale";
528 pub const PURCHASE_OF_PPE: &str = "PurchaseOfPPE";
529 pub const SALE_OF_PPE: &str = "SaleOfPPE";
530 pub const CAPITAL_EXPENDITURE: &str = "CapitalExpenditure";
531 pub const NET_BUSINESS_PURCHASE_AND_SALE: &str = "NetBusinessPurchaseAndSale";
532 pub const PURCHASE_OF_BUSINESS: &str = "PurchaseOfBusiness";
533 pub const SALE_OF_BUSINESS: &str = "SaleOfBusiness";
534 pub const NET_INVESTMENT_PURCHASE_AND_SALE: &str = "NetInvestmentPurchaseAndSale";
535 pub const PURCHASE_OF_INVESTMENT: &str = "PurchaseOfInvestment";
536 pub const SALE_OF_INVESTMENT: &str = "SaleOfInvestment";
537 pub const NET_OTHER_INVESTING_CHANGES: &str = "NetOtherInvestingChanges";
538 pub const FINANCING_CASH_FLOW: &str = "FinancingCashFlow";
539 pub const CASH_FLOW_FROM_CONTINUING_FINANCING_ACTIVITIES: &str =
540 "CashFlowFromContinuingFinancingActivities";
541 pub const NET_ISSUANCE_PAYMENTS_OF_DEBT: &str = "NetIssuancePaymentsOfDebt";
542 pub const NET_LONG_TERM_DEBT_ISSUANCE: &str = "NetLongTermDebtIssuance";
543 pub const LONG_TERM_DEBT_ISSUANCE: &str = "LongTermDebtIssuance";
544 pub const LONG_TERM_DEBT_PAYMENTS: &str = "LongTermDebtPayments";
545 pub const NET_SHORT_TERM_DEBT_ISSUANCE: &str = "NetShortTermDebtIssuance";
546 pub const NET_COMMON_STOCK_ISSUANCE: &str = "NetCommonStockIssuance";
547 pub const COMMON_STOCK_ISSUANCE: &str = "CommonStockIssuance";
548 pub const COMMON_STOCK_PAYMENTS: &str = "CommonStockPayments";
549 pub const REPURCHASE_OF_CAPITAL_STOCK: &str = "RepurchaseOfCapitalStock";
550 pub const CASH_DIVIDENDS_PAID: &str = "CashDividendsPaid";
551 pub const COMMON_STOCK_DIVIDEND_PAID: &str = "CommonStockDividendPaid";
552 pub const NET_OTHER_FINANCING_CHARGES: &str = "NetOtherFinancingCharges";
553 pub const END_CASH_POSITION: &str = "EndCashPosition";
554 pub const BEGINNING_CASH_POSITION: &str = "BeginningCashPosition";
555 pub const CHANGESIN_CASH: &str = "ChangesinCash";
556 pub const EFFECT_OF_EXCHANGE_RATE_CHANGES: &str = "EffectOfExchangeRateChanges";
557 pub const FREE_CASH_FLOW: &str = "FreeCashFlow";
558 pub const CAPITAL_EXPENDITURE_REPORTED: &str = "CapitalExpenditureReported";
559}
560
561#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
563pub enum StatementType {
564 Income,
566 Balance,
568 CashFlow,
570}
571
572impl StatementType {
573 pub fn as_str(&self) -> &'static str {
575 match self {
576 StatementType::Income => "income",
577 StatementType::Balance => "balance",
578 StatementType::CashFlow => "cashflow",
579 }
580 }
581
582 pub fn get_fields(&self) -> &'static [&'static str] {
586 match self {
587 StatementType::Income => &INCOME_STATEMENT_FIELDS,
588 StatementType::Balance => &BALANCE_SHEET_FIELDS,
589 StatementType::CashFlow => &CASH_FLOW_FIELDS,
590 }
591 }
592}
593
594impl std::str::FromStr for StatementType {
595 type Err = ();
596
597 fn from_str(s: &str) -> Result<Self, Self::Err> {
600 match s.to_lowercase().as_str() {
601 "income" | "income-statement" => Ok(StatementType::Income),
602 "balance" | "balance-sheet" => Ok(StatementType::Balance),
603 "cash" | "cashflow" | "cash-flow" => Ok(StatementType::CashFlow),
604 _ => Err(()),
605 }
606 }
607}
608
609const INCOME_STATEMENT_FIELDS: [&str; 30] = [
611 fundamental_types::TOTAL_REVENUE,
612 fundamental_types::OPERATING_REVENUE,
613 fundamental_types::COST_OF_REVENUE,
614 fundamental_types::GROSS_PROFIT,
615 fundamental_types::OPERATING_EXPENSE,
616 fundamental_types::SELLING_GENERAL_AND_ADMIN,
617 fundamental_types::RESEARCH_AND_DEVELOPMENT,
618 fundamental_types::OPERATING_INCOME,
619 fundamental_types::NET_INTEREST_INCOME,
620 fundamental_types::INTEREST_EXPENSE,
621 fundamental_types::INTEREST_INCOME,
622 fundamental_types::NET_NON_OPERATING_INTEREST_INCOME_EXPENSE,
623 fundamental_types::OTHER_INCOME_EXPENSE,
624 fundamental_types::PRETAX_INCOME,
625 fundamental_types::TAX_PROVISION,
626 fundamental_types::NET_INCOME_COMMON_STOCKHOLDERS,
627 fundamental_types::NET_INCOME,
628 fundamental_types::DILUTED_EPS,
629 fundamental_types::BASIC_EPS,
630 fundamental_types::DILUTED_AVERAGE_SHARES,
631 fundamental_types::BASIC_AVERAGE_SHARES,
632 fundamental_types::EBIT,
633 fundamental_types::EBITDA,
634 fundamental_types::RECONCILED_COST_OF_REVENUE,
635 fundamental_types::RECONCILED_DEPRECIATION,
636 fundamental_types::NET_INCOME_FROM_CONTINUING_OPERATION_NET_MINORITY_INTEREST,
637 fundamental_types::NORMALIZED_EBITDA,
638 fundamental_types::TOTAL_EXPENSES,
639 fundamental_types::TOTAL_OPERATING_INCOME_AS_REPORTED,
640 fundamental_types::DEPRECIATION_AND_AMORTIZATION,
641];
642
643const BALANCE_SHEET_FIELDS: [&str; 48] = [
645 fundamental_types::TOTAL_ASSETS,
646 fundamental_types::CURRENT_ASSETS,
647 fundamental_types::CASH_CASH_EQUIVALENTS_AND_SHORT_TERM_INVESTMENTS,
648 fundamental_types::CASH_AND_CASH_EQUIVALENTS,
649 fundamental_types::CASH_FINANCIAL,
650 fundamental_types::RECEIVABLES,
651 fundamental_types::ACCOUNTS_RECEIVABLE,
652 fundamental_types::INVENTORY,
653 fundamental_types::PREPAID_ASSETS,
654 fundamental_types::OTHER_CURRENT_ASSETS,
655 fundamental_types::TOTAL_NON_CURRENT_ASSETS,
656 fundamental_types::NET_PPE,
657 fundamental_types::GROSS_PPE,
658 fundamental_types::ACCUMULATED_DEPRECIATION,
659 fundamental_types::GOODWILL,
660 fundamental_types::GOODWILL_AND_OTHER_INTANGIBLE_ASSETS,
661 fundamental_types::OTHER_INTANGIBLE_ASSETS,
662 fundamental_types::INVESTMENTS_AND_ADVANCES,
663 fundamental_types::LONG_TERM_EQUITY_INVESTMENT,
664 fundamental_types::OTHER_NON_CURRENT_ASSETS,
665 fundamental_types::TOTAL_LIABILITIES_NET_MINORITY_INTEREST,
666 fundamental_types::CURRENT_LIABILITIES,
667 fundamental_types::PAYABLES_AND_ACCRUED_EXPENSES,
668 fundamental_types::ACCOUNTS_PAYABLE,
669 fundamental_types::CURRENT_DEBT,
670 fundamental_types::CURRENT_DEFERRED_REVENUE,
671 fundamental_types::OTHER_CURRENT_LIABILITIES,
672 fundamental_types::TOTAL_NON_CURRENT_LIABILITIES_NET_MINORITY_INTEREST,
673 fundamental_types::LONG_TERM_DEBT,
674 fundamental_types::LONG_TERM_DEBT_AND_CAPITAL_LEASE_OBLIGATION,
675 fundamental_types::NON_CURRENT_DEFERRED_REVENUE,
676 fundamental_types::NON_CURRENT_DEFERRED_TAXES_LIABILITIES,
677 fundamental_types::OTHER_NON_CURRENT_LIABILITIES,
678 fundamental_types::STOCKHOLDERS_EQUITY,
679 fundamental_types::COMMON_STOCK_EQUITY,
680 fundamental_types::COMMON_STOCK,
681 fundamental_types::RETAINED_EARNINGS,
682 fundamental_types::ADDITIONAL_PAID_IN_CAPITAL,
683 fundamental_types::TREASURY_STOCK,
684 fundamental_types::TOTAL_EQUITY_GROSS_MINORITY_INTEREST,
685 fundamental_types::WORKING_CAPITAL,
686 fundamental_types::INVESTED_CAPITAL,
687 fundamental_types::TANGIBLE_BOOK_VALUE,
688 fundamental_types::TOTAL_DEBT,
689 fundamental_types::NET_DEBT,
690 fundamental_types::SHARE_ISSUED,
691 fundamental_types::ORDINARY_SHARES_NUMBER,
692 fundamental_types::DEPRECIATION_AND_AMORTIZATION,
693];
694
695const CASH_FLOW_FIELDS: [&str; 47] = [
697 fundamental_types::OPERATING_CASH_FLOW,
698 fundamental_types::CASH_FLOW_FROM_CONTINUING_OPERATING_ACTIVITIES,
699 fundamental_types::NET_INCOME_FROM_CONTINUING_OPERATIONS,
700 fundamental_types::DEPRECIATION_AND_AMORTIZATION,
701 fundamental_types::DEFERRED_INCOME_TAX,
702 fundamental_types::CHANGE_IN_WORKING_CAPITAL,
703 fundamental_types::CHANGE_IN_RECEIVABLES,
704 fundamental_types::CHANGES_IN_ACCOUNT_RECEIVABLES,
705 fundamental_types::CHANGE_IN_INVENTORY,
706 fundamental_types::CHANGE_IN_ACCOUNT_PAYABLE,
707 fundamental_types::CHANGE_IN_OTHER_WORKING_CAPITAL,
708 fundamental_types::STOCK_BASED_COMPENSATION,
709 fundamental_types::OTHER_NON_CASH_ITEMS,
710 fundamental_types::INVESTING_CASH_FLOW,
711 fundamental_types::CASH_FLOW_FROM_CONTINUING_INVESTING_ACTIVITIES,
712 fundamental_types::NET_PPE_PURCHASE_AND_SALE,
713 fundamental_types::PURCHASE_OF_PPE,
714 fundamental_types::SALE_OF_PPE,
715 fundamental_types::CAPITAL_EXPENDITURE,
716 fundamental_types::NET_BUSINESS_PURCHASE_AND_SALE,
717 fundamental_types::PURCHASE_OF_BUSINESS,
718 fundamental_types::SALE_OF_BUSINESS,
719 fundamental_types::NET_INVESTMENT_PURCHASE_AND_SALE,
720 fundamental_types::PURCHASE_OF_INVESTMENT,
721 fundamental_types::SALE_OF_INVESTMENT,
722 fundamental_types::NET_OTHER_INVESTING_CHANGES,
723 fundamental_types::FINANCING_CASH_FLOW,
724 fundamental_types::CASH_FLOW_FROM_CONTINUING_FINANCING_ACTIVITIES,
725 fundamental_types::NET_ISSUANCE_PAYMENTS_OF_DEBT,
726 fundamental_types::NET_LONG_TERM_DEBT_ISSUANCE,
727 fundamental_types::LONG_TERM_DEBT_ISSUANCE,
728 fundamental_types::LONG_TERM_DEBT_PAYMENTS,
729 fundamental_types::NET_SHORT_TERM_DEBT_ISSUANCE,
730 fundamental_types::NET_COMMON_STOCK_ISSUANCE,
731 fundamental_types::COMMON_STOCK_ISSUANCE,
732 fundamental_types::COMMON_STOCK_PAYMENTS,
733 fundamental_types::REPURCHASE_OF_CAPITAL_STOCK,
734 fundamental_types::CASH_DIVIDENDS_PAID,
735 fundamental_types::COMMON_STOCK_DIVIDEND_PAID,
736 fundamental_types::NET_OTHER_FINANCING_CHARGES,
737 fundamental_types::END_CASH_POSITION,
738 fundamental_types::BEGINNING_CASH_POSITION,
739 fundamental_types::CHANGESIN_CASH,
740 fundamental_types::EFFECT_OF_EXCHANGE_RATE_CHANGES,
741 fundamental_types::FREE_CASH_FLOW,
742 fundamental_types::CAPITAL_EXPENDITURE_REPORTED,
743 fundamental_types::DEPRECIATION_AND_AMORTIZATION,
744];
745
746#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
748pub enum Frequency {
749 Annual,
751 Quarterly,
753}
754
755impl Frequency {
756 pub fn as_str(&self) -> &'static str {
758 match self {
759 Frequency::Annual => "annual",
760 Frequency::Quarterly => "quarterly",
761 }
762 }
763
764 pub fn prefix(&self, field: &str) -> String {
775 format!("{}{}", self.as_str(), field)
776 }
777}
778
779impl std::str::FromStr for Frequency {
780 type Err = ();
781
782 fn from_str(s: &str) -> Result<Self, Self::Err> {
785 match s.to_lowercase().as_str() {
786 "annual" | "yearly" | "year" => Ok(Frequency::Annual),
787 "quarterly" | "quarter" | "q" => Ok(Frequency::Quarterly),
788 _ => Err(()),
789 }
790 }
791}
792
793#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
795pub enum Interval {
796 #[serde(rename = "1m")]
798 OneMinute,
799 #[serde(rename = "5m")]
801 FiveMinutes,
802 #[serde(rename = "15m")]
804 FifteenMinutes,
805 #[serde(rename = "30m")]
807 ThirtyMinutes,
808 #[serde(rename = "1h")]
810 OneHour,
811 #[serde(rename = "1d")]
813 OneDay,
814 #[serde(rename = "1wk")]
816 OneWeek,
817 #[serde(rename = "1mo")]
819 OneMonth,
820 #[serde(rename = "3mo")]
822 ThreeMonths,
823}
824
825impl Interval {
826 pub fn as_str(&self) -> &'static str {
828 match self {
829 Interval::OneMinute => "1m",
830 Interval::FiveMinutes => "5m",
831 Interval::FifteenMinutes => "15m",
832 Interval::ThirtyMinutes => "30m",
833 Interval::OneHour => "1h",
834 Interval::OneDay => "1d",
835 Interval::OneWeek => "1wk",
836 Interval::OneMonth => "1mo",
837 Interval::ThreeMonths => "3mo",
838 }
839 }
840}
841
842impl std::fmt::Display for Interval {
843 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
844 f.write_str(self.as_str())
845 }
846}
847
848impl std::str::FromStr for Interval {
849 type Err = ();
850
851 fn from_str(s: &str) -> Result<Self, Self::Err> {
854 match s.trim().to_lowercase().as_str() {
855 "1m" => Ok(Interval::OneMinute),
856 "5m" => Ok(Interval::FiveMinutes),
857 "15m" => Ok(Interval::FifteenMinutes),
858 "30m" => Ok(Interval::ThirtyMinutes),
859 "1h" => Ok(Interval::OneHour),
860 "1d" => Ok(Interval::OneDay),
861 "1wk" => Ok(Interval::OneWeek),
862 "1mo" => Ok(Interval::OneMonth),
863 "3mo" => Ok(Interval::ThreeMonths),
864 _ => Err(()),
865 }
866 }
867}
868
869#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
871pub enum TimeRange {
872 #[serde(rename = "1d")]
874 OneDay,
875 #[serde(rename = "5d")]
877 FiveDays,
878 #[serde(rename = "1mo")]
880 OneMonth,
881 #[serde(rename = "3mo")]
883 ThreeMonths,
884 #[serde(rename = "6mo")]
886 SixMonths,
887 #[serde(rename = "1y")]
889 OneYear,
890 #[serde(rename = "2y")]
892 TwoYears,
893 #[serde(rename = "5y")]
895 FiveYears,
896 #[serde(rename = "10y")]
898 TenYears,
899 #[serde(rename = "ytd")]
901 YearToDate,
902 #[serde(rename = "max")]
904 Max,
905}
906
907impl TimeRange {
908 pub fn as_str(&self) -> &'static str {
910 match self {
911 TimeRange::OneDay => "1d",
912 TimeRange::FiveDays => "5d",
913 TimeRange::OneMonth => "1mo",
914 TimeRange::ThreeMonths => "3mo",
915 TimeRange::SixMonths => "6mo",
916 TimeRange::OneYear => "1y",
917 TimeRange::TwoYears => "2y",
918 TimeRange::FiveYears => "5y",
919 TimeRange::TenYears => "10y",
920 TimeRange::YearToDate => "ytd",
921 TimeRange::Max => "max",
922 }
923 }
924
925 pub fn default_interval(&self) -> Interval {
929 match self {
930 TimeRange::OneDay => Interval::FiveMinutes,
931 TimeRange::FiveDays => Interval::FifteenMinutes,
932 TimeRange::OneMonth
933 | TimeRange::ThreeMonths
934 | TimeRange::SixMonths
935 | TimeRange::OneYear
936 | TimeRange::YearToDate => Interval::OneDay,
937 TimeRange::TwoYears | TimeRange::FiveYears => Interval::OneWeek,
938 TimeRange::TenYears | TimeRange::Max => Interval::OneMonth,
939 }
940 }
941
942 pub const fn approx_duration_secs(&self) -> i64 {
947 const DAY: i64 = 86_400;
948 match self {
949 TimeRange::OneDay => DAY,
950 TimeRange::FiveDays => 5 * DAY,
951 TimeRange::OneMonth => 30 * DAY,
952 TimeRange::ThreeMonths => 90 * DAY,
953 TimeRange::SixMonths => 180 * DAY,
954 TimeRange::OneYear | TimeRange::YearToDate => 365 * DAY,
955 TimeRange::TwoYears => 730 * DAY,
956 TimeRange::FiveYears => 1_825 * DAY,
957 TimeRange::TenYears => 3_650 * DAY,
958 TimeRange::Max => 36_500 * DAY,
959 }
960 }
961}
962
963impl std::fmt::Display for TimeRange {
964 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
965 f.write_str(self.as_str())
966 }
967}
968
969impl std::str::FromStr for TimeRange {
970 type Err = ();
971
972 fn from_str(s: &str) -> Result<Self, Self::Err> {
976 match s.trim().to_lowercase().as_str() {
977 "1d" => Ok(TimeRange::OneDay),
978 "5d" | "1wk" => Ok(TimeRange::FiveDays),
979 "1mo" => Ok(TimeRange::OneMonth),
980 "3mo" => Ok(TimeRange::ThreeMonths),
981 "6mo" => Ok(TimeRange::SixMonths),
982 "1y" => Ok(TimeRange::OneYear),
983 "2y" => Ok(TimeRange::TwoYears),
984 "5y" => Ok(TimeRange::FiveYears),
985 "10y" => Ok(TimeRange::TenYears),
986 "ytd" => Ok(TimeRange::YearToDate),
987 "max" => Ok(TimeRange::Max),
988 _ => Err(()),
989 }
990 }
991}
992
993#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
998pub enum Region {
999 Argentina,
1001 Australia,
1003 Brazil,
1005 Canada,
1007 China,
1009 Denmark,
1011 Finland,
1013 France,
1015 Germany,
1017 Greece,
1019 HongKong,
1021 India,
1023 Israel,
1025 Italy,
1027 Japan,
1029 Korea,
1031 Malaysia,
1033 Mexico,
1035 NewZealand,
1037 Norway,
1039 Portugal,
1041 Qatar,
1043 Russia,
1045 Singapore,
1047 Spain,
1049 Sweden,
1051 Taiwan,
1053 Thailand,
1055 Turkey,
1057 UnitedKingdom,
1059 #[default]
1061 UnitedStates,
1062 Vietnam,
1064}
1065
1066impl Region {
1067 pub fn lang(&self) -> &'static str {
1078 match self {
1079 Region::Argentina => "es-AR",
1080 Region::Australia => "en-AU",
1081 Region::Brazil => "pt-BR",
1082 Region::Canada => "en-CA",
1083 Region::China => "zh-CN",
1084 Region::Denmark => "da-DK",
1085 Region::Finland => "fi-FI",
1086 Region::France => "fr-FR",
1087 Region::Germany => "de-DE",
1088 Region::Greece => "el-GR",
1089 Region::HongKong => "zh-Hant-HK",
1090 Region::India => "en-IN",
1091 Region::Israel => "he-IL",
1092 Region::Italy => "it-IT",
1093 Region::Japan => "ja-JP",
1094 Region::Korea => "ko-KR",
1095 Region::Malaysia => "ms-MY",
1096 Region::Mexico => "es-MX",
1097 Region::NewZealand => "en-NZ",
1098 Region::Norway => "nb-NO",
1099 Region::Portugal => "pt-PT",
1100 Region::Qatar => "ar-QA",
1101 Region::Russia => "ru-RU",
1102 Region::Singapore => "en-SG",
1103 Region::Spain => "es-ES",
1104 Region::Sweden => "sv-SE",
1105 Region::Taiwan => "zh-TW",
1106 Region::Thailand => "th-TH",
1107 Region::Turkey => "tr-TR",
1108 Region::UnitedKingdom => "en-GB",
1109 Region::UnitedStates => "en-US",
1110 Region::Vietnam => "vi-VN",
1111 }
1112 }
1113
1114 pub fn region(&self) -> &'static str {
1125 match self {
1126 Region::Argentina => "AR",
1127 Region::Australia => "AU",
1128 Region::Brazil => "BR",
1129 Region::Canada => "CA",
1130 Region::China => "CN",
1131 Region::Denmark => "DK",
1132 Region::Finland => "FI",
1133 Region::France => "FR",
1134 Region::Germany => "DE",
1135 Region::Greece => "GR",
1136 Region::HongKong => "HK",
1137 Region::India => "IN",
1138 Region::Israel => "IL",
1139 Region::Italy => "IT",
1140 Region::Japan => "JP",
1141 Region::Korea => "KR",
1142 Region::Malaysia => "MY",
1143 Region::Mexico => "MX",
1144 Region::NewZealand => "NZ",
1145 Region::Norway => "NO",
1146 Region::Portugal => "PT",
1147 Region::Qatar => "QA",
1148 Region::Russia => "RU",
1149 Region::Singapore => "SG",
1150 Region::Spain => "ES",
1151 Region::Sweden => "SE",
1152 Region::Taiwan => "TW",
1153 Region::Thailand => "TH",
1154 Region::Turkey => "TR",
1155 Region::UnitedKingdom => "GB",
1156 Region::UnitedStates => "US",
1157 Region::Vietnam => "VN",
1158 }
1159 }
1160
1161 pub const fn utc_offset_secs(&self) -> i64 {
1176 match self {
1177 Region::UnitedStates | Region::Canada => -18_000,
1179 Region::Mexico => -21_600,
1181 Region::Argentina | Region::Brazil => -10_800,
1183 Region::UnitedKingdom | Region::Portugal => 0,
1185 Region::France
1187 | Region::Germany
1188 | Region::Italy
1189 | Region::Spain
1190 | Region::Norway
1191 | Region::Sweden
1192 | Region::Denmark
1193 | Region::Finland => 3_600,
1194 Region::Greece | Region::Israel => 7_200,
1196 Region::Turkey | Region::Russia | Region::Qatar => 10_800,
1198 Region::India => 19_800,
1200 Region::Thailand | Region::Vietnam => 25_200,
1202 Region::China
1204 | Region::HongKong
1205 | Region::Singapore
1206 | Region::Malaysia
1207 | Region::Taiwan => 28_800,
1208 Region::Japan | Region::Korea => 32_400,
1210 Region::Australia => 36_000,
1212 Region::NewZealand => 43_200,
1214 }
1215 }
1216}
1217
1218impl std::str::FromStr for Region {
1219 type Err = ();
1220
1221 fn from_str(s: &str) -> Result<Self, Self::Err> {
1222 match s.to_uppercase().as_str() {
1223 "AR" => Ok(Region::Argentina),
1224 "AU" => Ok(Region::Australia),
1225 "BR" => Ok(Region::Brazil),
1226 "CA" => Ok(Region::Canada),
1227 "CN" => Ok(Region::China),
1228 "DK" => Ok(Region::Denmark),
1229 "FI" => Ok(Region::Finland),
1230 "FR" => Ok(Region::France),
1231 "DE" => Ok(Region::Germany),
1232 "GR" => Ok(Region::Greece),
1233 "HK" => Ok(Region::HongKong),
1234 "IN" => Ok(Region::India),
1235 "IL" => Ok(Region::Israel),
1236 "IT" => Ok(Region::Italy),
1237 "JP" => Ok(Region::Japan),
1238 "KR" => Ok(Region::Korea),
1239 "MY" => Ok(Region::Malaysia),
1240 "MX" => Ok(Region::Mexico),
1241 "NZ" => Ok(Region::NewZealand),
1242 "NO" => Ok(Region::Norway),
1243 "PT" => Ok(Region::Portugal),
1244 "QA" => Ok(Region::Qatar),
1245 "RU" => Ok(Region::Russia),
1246 "SG" => Ok(Region::Singapore),
1247 "ES" => Ok(Region::Spain),
1248 "SE" => Ok(Region::Sweden),
1249 "TW" => Ok(Region::Taiwan),
1250 "TH" => Ok(Region::Thailand),
1251 "TR" => Ok(Region::Turkey),
1252 "GB" | "UK" => Ok(Region::UnitedKingdom),
1253 "US" => Ok(Region::UnitedStates),
1254 "VN" => Ok(Region::Vietnam),
1255 _ => Err(()),
1256 }
1257 }
1258}
1259
1260impl From<Region> for String {
1261 fn from(v: Region) -> Self {
1264 v.region().to_lowercase()
1265 }
1266}
1267
1268#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
1274pub enum ValueFormat {
1275 #[default]
1278 Raw,
1279 Pretty,
1282 Both,
1285}
1286
1287impl std::str::FromStr for ValueFormat {
1288 type Err = ();
1289
1290 fn from_str(s: &str) -> Result<Self, Self::Err> {
1291 match s.to_lowercase().as_str() {
1292 "raw" => Ok(ValueFormat::Raw),
1293 "pretty" | "fmt" => Ok(ValueFormat::Pretty),
1294 "both" | "full" => Ok(ValueFormat::Both),
1295 _ => Err(()),
1296 }
1297 }
1298}
1299
1300impl ValueFormat {
1301 pub fn parse(s: &str) -> Option<Self> {
1303 s.parse().ok()
1304 }
1305
1306 pub fn as_str(&self) -> &'static str {
1308 match self {
1309 ValueFormat::Raw => "raw",
1310 ValueFormat::Pretty => "pretty",
1311 ValueFormat::Both => "both",
1312 }
1313 }
1314
1315 pub fn transform(&self, value: serde_json::Value) -> serde_json::Value {
1342 match self {
1343 ValueFormat::Both => value, _ => self.transform_recursive(value),
1345 }
1346 }
1347
1348 fn transform_recursive(&self, value: serde_json::Value) -> serde_json::Value {
1349 use serde_json::Value;
1350
1351 match value {
1352 Value::Object(map) => {
1353 if self.is_formatted_value(&map) {
1355 return self.extract_value(&map);
1356 }
1357
1358 let transformed: serde_json::Map<String, Value> = map
1360 .into_iter()
1361 .map(|(k, v)| (k, self.transform_recursive(v)))
1362 .collect();
1363 Value::Object(transformed)
1364 }
1365 Value::Array(arr) => Value::Array(
1366 arr.into_iter()
1367 .map(|v| self.transform_recursive(v))
1368 .collect(),
1369 ),
1370 other => other,
1372 }
1373 }
1374
1375 fn is_formatted_value(&self, map: &serde_json::Map<String, serde_json::Value>) -> bool {
1377 if !map.contains_key("raw") {
1381 return false;
1382 }
1383
1384 let known_keys = ["raw", "fmt", "longFmt"];
1385 let unknown_keys = map
1386 .keys()
1387 .filter(|k| !known_keys.contains(&k.as_str()))
1388 .count();
1389
1390 unknown_keys == 0
1392 }
1393
1394 fn extract_value(&self, map: &serde_json::Map<String, serde_json::Value>) -> serde_json::Value {
1396 match self {
1397 ValueFormat::Raw => {
1398 map.get("raw").cloned().unwrap_or(serde_json::Value::Null)
1400 }
1401 ValueFormat::Pretty => {
1402 map.get("fmt")
1404 .or_else(|| map.get("longFmt"))
1405 .cloned()
1406 .unwrap_or(serde_json::Value::Null)
1407 }
1408 ValueFormat::Both => {
1409 serde_json::Value::Object(map.clone())
1411 }
1412 }
1413 }
1414}
1415
1416pub mod industries {
1441 #[non_exhaustive]
1445 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1446 pub enum Industry {
1447 AgriculturalInputs,
1450 Aluminum,
1452 Coal,
1454 Copper,
1456 FarmProducts,
1458 ForestProducts,
1460 Gold,
1462 LumberAndWoodProduction,
1464 OtherIndustrialMetalsAndMining,
1466 OtherPreciousMetalsAndMining,
1468 Silver,
1470 Steel,
1472 ThermalCoal,
1474 Uranium,
1476 ApparelManufacturing,
1479 ApparelRetail,
1481 AutoAndTruckDealerships,
1483 AutoManufacturers,
1485 AutoParts,
1487 BeveragesBrewers,
1489 BeveragesNonAlcoholic,
1491 BeveragesWineriesAndDistilleries,
1493 Confectioners,
1495 DepartmentStores,
1497 DiscountStores,
1499 ElectronicGamingAndMultimedia,
1501 FoodDistribution,
1503 FootwearAndAccessories,
1505 FurnishingsFixturesAndAppliances,
1507 Gambling,
1509 GroceryStores,
1511 HomeImprovementRetail,
1513 HouseholdAndPersonalProducts,
1515 InternetRetail,
1517 Leisure,
1519 Lodging,
1521 LuxuryGoods,
1523 PackagedFoods,
1525 PersonalServices,
1527 ResidentialConstruction,
1529 ResortsAndCasinos,
1531 Restaurants,
1533 SpecialtyRetail,
1535 TextileManufacturing,
1537 Tobacco,
1539 TravelServices,
1541 OilAndGasDrilling,
1544 OilAndGasEAndP,
1546 OilAndGasEquipmentAndServices,
1548 OilAndGasIntegrated,
1550 OilAndGasMidstream,
1552 OilAndGasRefiningAndMarketing,
1554 Solar,
1556 AssetManagement,
1559 BanksDiversified,
1561 BanksRegional,
1563 CapitalMarkets,
1565 CreditServices,
1567 FinancialDataAndStockExchanges,
1569 InsuranceBrokers,
1571 InsuranceDiversified,
1573 InsuranceLife,
1575 InsurancePropertyAndCasualty,
1577 InsuranceReinsurance,
1579 InsuranceSpecialty,
1581 MortgageFinance,
1583 ShellCompanies,
1585 Biotechnology,
1588 DiagnosticsAndResearch,
1590 DrugManufacturersGeneral,
1592 DrugManufacturersSpecialtyAndGeneric,
1594 HealthInformationServices,
1596 HealthcarePlans,
1598 MedicalCareFacilities,
1600 MedicalDevices,
1602 MedicalDistribution,
1604 MedicalInstrumentsAndSupplies,
1606 PharmaceuticalRetailers,
1608 AerospaceAndDefense,
1611 BuildingMaterials,
1613 BuildingProductsAndEquipment,
1615 BusinessEquipmentAndSupplies,
1617 ChemicalManufacturing,
1619 Chemicals,
1621 Conglomerates,
1623 ConsultingServices,
1625 ElectricalEquipmentAndParts,
1627 EngineeringAndConstruction,
1629 FarmAndHeavyConstructionMachinery,
1631 IndustrialDistribution,
1633 InfrastructureOperations,
1635 IntegratedFreightAndLogistics,
1637 ManufacturingDiversified,
1639 MarinePortsAndServices,
1641 MarineShipping,
1643 MetalFabrication,
1645 PaperAndPaperProducts,
1647 PollutionAndTreatmentControls,
1649 Railroads,
1651 RentalAndLeasingServices,
1653 SecurityAndProtectionServices,
1655 SpecialtyBusinessServices,
1657 SpecialtyChemicals,
1659 SpecialtyIndustrialMachinery,
1661 StaffingAndEmploymentServices,
1663 ToolsAndAccessories,
1665 Trucking,
1667 WasteManagement,
1669 RealEstateDevelopment,
1672 RealEstateDiversified,
1674 RealEstateServices,
1676 ReitDiversified,
1678 ReitHealthcareFacilities,
1680 ReitHotelAndMotel,
1682 ReitIndustrial,
1684 ReitMortgage,
1686 ReitOffice,
1688 ReitResidential,
1690 ReitRetail,
1692 ReitSpecialty,
1694 CommunicationEquipment,
1697 ComputerHardware,
1699 ConsumerElectronics,
1701 DataAnalytics,
1703 ElectronicComponents,
1705 ElectronicsAndComputerDistribution,
1707 HardwareAndSoftwareDistribution,
1709 InformationTechnologyServices,
1711 InternetContentAndInformation,
1713 ScientificAndTechnicalInstruments,
1715 SemiconductorEquipmentAndMaterials,
1717 Semiconductors,
1719 SoftwareApplication,
1721 SoftwareInfrastructure,
1723 Broadcasting,
1726 Entertainment,
1728 Publishing,
1730 TelecomServices,
1732 UtilitiesDiversified,
1735 UtilitiesIndependentPowerProducers,
1737 UtilitiesRegulatedElectric,
1739 UtilitiesRegulatedGas,
1741 UtilitiesRegulatedWater,
1743 UtilitiesRenewable,
1745 ClosedEndFundDebt,
1748 ClosedEndFundEquity,
1750 ClosedEndFundForeign,
1752 ExchangeTradedFund,
1754 }
1755
1756 impl Industry {
1757 pub fn as_slug(self) -> &'static str {
1767 match self {
1768 Industry::AgriculturalInputs => "agricultural-inputs",
1769 Industry::Aluminum => "aluminum",
1770 Industry::Coal => "coal",
1771 Industry::Copper => "copper",
1772 Industry::FarmProducts => "farm-products",
1773 Industry::ForestProducts => "forest-products",
1774 Industry::Gold => "gold",
1775 Industry::LumberAndWoodProduction => "lumber-wood-production",
1776 Industry::OtherIndustrialMetalsAndMining => "other-industrial-metals-mining",
1777 Industry::OtherPreciousMetalsAndMining => "other-precious-metals-mining",
1778 Industry::Silver => "silver",
1779 Industry::Steel => "steel",
1780 Industry::ThermalCoal => "thermal-coal",
1781 Industry::Uranium => "uranium",
1782 Industry::ApparelManufacturing => "apparel-manufacturing",
1783 Industry::ApparelRetail => "apparel-retail",
1784 Industry::AutoAndTruckDealerships => "auto-truck-dealerships",
1785 Industry::AutoManufacturers => "auto-manufacturers",
1786 Industry::AutoParts => "auto-parts",
1787 Industry::BeveragesBrewers => "beverages-brewers",
1788 Industry::BeveragesNonAlcoholic => "beverages-non-alcoholic",
1789 Industry::BeveragesWineriesAndDistilleries => "beverages-wineries-distilleries",
1790 Industry::Confectioners => "confectioners",
1791 Industry::DepartmentStores => "department-stores",
1792 Industry::DiscountStores => "discount-stores",
1793 Industry::ElectronicGamingAndMultimedia => "electronic-gaming-multimedia",
1794 Industry::FoodDistribution => "food-distribution",
1795 Industry::FootwearAndAccessories => "footwear-accessories",
1796 Industry::FurnishingsFixturesAndAppliances => "furnishings-fixtures-appliances",
1797 Industry::Gambling => "gambling",
1798 Industry::GroceryStores => "grocery-stores",
1799 Industry::HomeImprovementRetail => "home-improvement-retail",
1800 Industry::HouseholdAndPersonalProducts => "household-personal-products",
1801 Industry::InternetRetail => "internet-retail",
1802 Industry::Leisure => "leisure",
1803 Industry::Lodging => "lodging",
1804 Industry::LuxuryGoods => "luxury-goods",
1805 Industry::PackagedFoods => "packaged-foods",
1806 Industry::PersonalServices => "personal-services",
1807 Industry::ResidentialConstruction => "residential-construction",
1808 Industry::ResortsAndCasinos => "resorts-casinos",
1809 Industry::Restaurants => "restaurants",
1810 Industry::SpecialtyRetail => "specialty-retail",
1811 Industry::TextileManufacturing => "textile-manufacturing",
1812 Industry::Tobacco => "tobacco",
1813 Industry::TravelServices => "travel-services",
1814 Industry::OilAndGasDrilling => "oil-gas-drilling",
1815 Industry::OilAndGasEAndP => "oil-gas-ep",
1816 Industry::OilAndGasEquipmentAndServices => "oil-gas-equipment-services",
1817 Industry::OilAndGasIntegrated => "oil-gas-integrated",
1818 Industry::OilAndGasMidstream => "oil-gas-midstream",
1819 Industry::OilAndGasRefiningAndMarketing => "oil-gas-refining-marketing",
1820 Industry::Solar => "solar",
1821 Industry::AssetManagement => "asset-management",
1822 Industry::BanksDiversified => "banks-diversified",
1823 Industry::BanksRegional => "banks-regional",
1824 Industry::CapitalMarkets => "capital-markets",
1825 Industry::CreditServices => "credit-services",
1826 Industry::FinancialDataAndStockExchanges => "financial-data-stock-exchanges",
1827 Industry::InsuranceBrokers => "insurance-brokers",
1828 Industry::InsuranceDiversified => "insurance-diversified",
1829 Industry::InsuranceLife => "insurance-life",
1830 Industry::InsurancePropertyAndCasualty => "insurance-property-casualty",
1831 Industry::InsuranceReinsurance => "insurance-reinsurance",
1832 Industry::InsuranceSpecialty => "insurance-specialty",
1833 Industry::MortgageFinance => "mortgage-finance",
1834 Industry::ShellCompanies => "shell-companies",
1835 Industry::Biotechnology => "biotechnology",
1836 Industry::DiagnosticsAndResearch => "diagnostics-research",
1837 Industry::DrugManufacturersGeneral => "drug-manufacturers-general",
1838 Industry::DrugManufacturersSpecialtyAndGeneric => {
1839 "drug-manufacturers-specialty-generic"
1840 }
1841 Industry::HealthInformationServices => "health-information-services",
1842 Industry::HealthcarePlans => "healthcare-plans",
1843 Industry::MedicalCareFacilities => "medical-care-facilities",
1844 Industry::MedicalDevices => "medical-devices",
1845 Industry::MedicalDistribution => "medical-distribution",
1846 Industry::MedicalInstrumentsAndSupplies => "medical-instruments-supplies",
1847 Industry::PharmaceuticalRetailers => "pharmaceutical-retailers",
1848 Industry::AerospaceAndDefense => "aerospace-defense",
1849 Industry::BuildingMaterials => "building-materials",
1850 Industry::BuildingProductsAndEquipment => "building-products-equipment",
1851 Industry::BusinessEquipmentAndSupplies => "business-equipment-supplies",
1852 Industry::ChemicalManufacturing => "chemical-manufacturing",
1853 Industry::Chemicals => "chemicals",
1854 Industry::Conglomerates => "conglomerates",
1855 Industry::ConsultingServices => "consulting-services",
1856 Industry::ElectricalEquipmentAndParts => "electrical-equipment-parts",
1857 Industry::EngineeringAndConstruction => "engineering-construction",
1858 Industry::FarmAndHeavyConstructionMachinery => "farm-heavy-construction-machinery",
1859 Industry::IndustrialDistribution => "industrial-distribution",
1860 Industry::InfrastructureOperations => "infrastructure-operations",
1861 Industry::IntegratedFreightAndLogistics => "integrated-freight-logistics",
1862 Industry::ManufacturingDiversified => "manufacturing-diversified",
1863 Industry::MarinePortsAndServices => "marine-ports-services",
1864 Industry::MarineShipping => "marine-shipping",
1865 Industry::MetalFabrication => "metal-fabrication",
1866 Industry::PaperAndPaperProducts => "paper-paper-products",
1867 Industry::PollutionAndTreatmentControls => "pollution-treatment-controls",
1868 Industry::Railroads => "railroads",
1869 Industry::RentalAndLeasingServices => "rental-leasing-services",
1870 Industry::SecurityAndProtectionServices => "security-protection-services",
1871 Industry::SpecialtyBusinessServices => "specialty-business-services",
1872 Industry::SpecialtyChemicals => "specialty-chemicals",
1873 Industry::SpecialtyIndustrialMachinery => "specialty-industrial-machinery",
1874 Industry::StaffingAndEmploymentServices => "staffing-employment-services",
1875 Industry::ToolsAndAccessories => "tools-accessories",
1876 Industry::Trucking => "trucking",
1877 Industry::WasteManagement => "waste-management",
1878 Industry::RealEstateDevelopment => "real-estate-development",
1879 Industry::RealEstateDiversified => "real-estate-diversified",
1880 Industry::RealEstateServices => "real-estate-services",
1881 Industry::ReitDiversified => "reit-diversified",
1882 Industry::ReitHealthcareFacilities => "reit-healthcare-facilities",
1883 Industry::ReitHotelAndMotel => "reit-hotel-motel",
1884 Industry::ReitIndustrial => "reit-industrial",
1885 Industry::ReitMortgage => "reit-mortgage",
1886 Industry::ReitOffice => "reit-office",
1887 Industry::ReitResidential => "reit-residential",
1888 Industry::ReitRetail => "reit-retail",
1889 Industry::ReitSpecialty => "reit-specialty",
1890 Industry::CommunicationEquipment => "communication-equipment",
1891 Industry::ComputerHardware => "computer-hardware",
1892 Industry::ConsumerElectronics => "consumer-electronics",
1893 Industry::DataAnalytics => "data-analytics",
1894 Industry::ElectronicComponents => "electronic-components",
1895 Industry::ElectronicsAndComputerDistribution => "electronics-computer-distribution",
1896 Industry::HardwareAndSoftwareDistribution => "hardware-software-distribution",
1897 Industry::InformationTechnologyServices => "information-technology-services",
1898 Industry::InternetContentAndInformation => "internet-content-information",
1899 Industry::ScientificAndTechnicalInstruments => "scientific-technical-instruments",
1900 Industry::SemiconductorEquipmentAndMaterials => "semiconductor-equipment-materials",
1901 Industry::Semiconductors => "semiconductors",
1902 Industry::SoftwareApplication => "software-application",
1903 Industry::SoftwareInfrastructure => "software-infrastructure",
1904 Industry::Broadcasting => "broadcasting",
1905 Industry::Entertainment => "entertainment",
1906 Industry::Publishing => "publishing",
1907 Industry::TelecomServices => "telecom-services",
1908 Industry::UtilitiesDiversified => "utilities-diversified",
1909 Industry::UtilitiesIndependentPowerProducers => {
1910 "utilities-independent-power-producers"
1911 }
1912 Industry::UtilitiesRegulatedElectric => "utilities-regulated-electric",
1913 Industry::UtilitiesRegulatedGas => "utilities-regulated-gas",
1914 Industry::UtilitiesRegulatedWater => "utilities-regulated-water",
1915 Industry::UtilitiesRenewable => "utilities-renewable",
1916 Industry::ClosedEndFundDebt => "closed-end-fund-debt",
1917 Industry::ClosedEndFundEquity => "closed-end-fund-equity",
1918 Industry::ClosedEndFundForeign => "closed-end-fund-foreign",
1919 Industry::ExchangeTradedFund => "exchange-traded-fund",
1920 }
1921 }
1922
1923 pub fn screener_value(self) -> &'static str {
1933 match self {
1934 Industry::AgriculturalInputs => "Agricultural Inputs",
1935 Industry::Aluminum => "Aluminum",
1936 Industry::Coal => "Coal",
1937 Industry::Copper => "Copper",
1938 Industry::FarmProducts => "Farm Products",
1939 Industry::ForestProducts => "Forest Products",
1940 Industry::Gold => "Gold",
1941 Industry::LumberAndWoodProduction => "Lumber & Wood Production",
1942 Industry::OtherIndustrialMetalsAndMining => "Other Industrial Metals & Mining",
1943 Industry::OtherPreciousMetalsAndMining => "Other Precious Metals & Mining",
1944 Industry::Silver => "Silver",
1945 Industry::Steel => "Steel",
1946 Industry::ThermalCoal => "Thermal Coal",
1947 Industry::Uranium => "Uranium",
1948 Industry::ApparelManufacturing => "Apparel Manufacturing",
1949 Industry::ApparelRetail => "Apparel Retail",
1950 Industry::AutoAndTruckDealerships => "Auto & Truck Dealerships",
1951 Industry::AutoManufacturers => "Auto Manufacturers",
1952 Industry::AutoParts => "Auto Parts",
1953 Industry::BeveragesBrewers => "Beverages - Brewers",
1954 Industry::BeveragesNonAlcoholic => "Beverages - Non-Alcoholic",
1955 Industry::BeveragesWineriesAndDistilleries => "Beverages - Wineries & Distilleries",
1956 Industry::Confectioners => "Confectioners",
1957 Industry::DepartmentStores => "Department Stores",
1958 Industry::DiscountStores => "Discount Stores",
1959 Industry::ElectronicGamingAndMultimedia => "Electronic Gaming & Multimedia",
1960 Industry::FoodDistribution => "Food Distribution",
1961 Industry::FootwearAndAccessories => "Footwear & Accessories",
1962 Industry::FurnishingsFixturesAndAppliances => "Furnishings, Fixtures & Appliances",
1963 Industry::Gambling => "Gambling",
1964 Industry::GroceryStores => "Grocery Stores",
1965 Industry::HomeImprovementRetail => "Home Improvement Retail",
1966 Industry::HouseholdAndPersonalProducts => "Household & Personal Products",
1967 Industry::InternetRetail => "Internet Retail",
1968 Industry::Leisure => "Leisure",
1969 Industry::Lodging => "Lodging",
1970 Industry::LuxuryGoods => "Luxury Goods",
1971 Industry::PackagedFoods => "Packaged Foods",
1972 Industry::PersonalServices => "Personal Services",
1973 Industry::ResidentialConstruction => "Residential Construction",
1974 Industry::ResortsAndCasinos => "Resorts & Casinos",
1975 Industry::Restaurants => "Restaurants",
1976 Industry::SpecialtyRetail => "Specialty Retail",
1977 Industry::TextileManufacturing => "Textile Manufacturing",
1978 Industry::Tobacco => "Tobacco",
1979 Industry::TravelServices => "Travel Services",
1980 Industry::OilAndGasDrilling => "Oil & Gas Drilling",
1981 Industry::OilAndGasEAndP => "Oil & Gas E&P",
1982 Industry::OilAndGasEquipmentAndServices => "Oil & Gas Equipment & Services",
1983 Industry::OilAndGasIntegrated => "Oil & Gas Integrated",
1984 Industry::OilAndGasMidstream => "Oil & Gas Midstream",
1985 Industry::OilAndGasRefiningAndMarketing => "Oil & Gas Refining & Marketing",
1986 Industry::Solar => "Solar",
1987 Industry::AssetManagement => "Asset Management",
1988 Industry::BanksDiversified => "Banks - Diversified",
1989 Industry::BanksRegional => "Banks - Regional",
1990 Industry::CapitalMarkets => "Capital Markets",
1991 Industry::CreditServices => "Credit Services",
1992 Industry::FinancialDataAndStockExchanges => "Financial Data & Stock Exchanges",
1993 Industry::InsuranceBrokers => "Insurance Brokers",
1994 Industry::InsuranceDiversified => "Insurance - Diversified",
1995 Industry::InsuranceLife => "Insurance - Life",
1996 Industry::InsurancePropertyAndCasualty => "Insurance - Property & Casualty",
1997 Industry::InsuranceReinsurance => "Insurance - Reinsurance",
1998 Industry::InsuranceSpecialty => "Insurance - Specialty",
1999 Industry::MortgageFinance => "Mortgage Finance",
2000 Industry::ShellCompanies => "Shell Companies",
2001 Industry::Biotechnology => "Biotechnology",
2002 Industry::DiagnosticsAndResearch => "Diagnostics & Research",
2003 Industry::DrugManufacturersGeneral => "Drug Manufacturers - General",
2004 Industry::DrugManufacturersSpecialtyAndGeneric => {
2005 "Drug Manufacturers - Specialty & Generic"
2006 }
2007 Industry::HealthInformationServices => "Health Information Services",
2008 Industry::HealthcarePlans => "Healthcare Plans",
2009 Industry::MedicalCareFacilities => "Medical Care Facilities",
2010 Industry::MedicalDevices => "Medical Devices",
2011 Industry::MedicalDistribution => "Medical Distribution",
2012 Industry::MedicalInstrumentsAndSupplies => "Medical Instruments & Supplies",
2013 Industry::PharmaceuticalRetailers => "Pharmaceutical Retailers",
2014 Industry::AerospaceAndDefense => "Aerospace & Defense",
2015 Industry::BuildingMaterials => "Building Materials",
2016 Industry::BuildingProductsAndEquipment => "Building Products & Equipment",
2017 Industry::BusinessEquipmentAndSupplies => "Business Equipment & Supplies",
2018 Industry::ChemicalManufacturing => "Chemical Manufacturing",
2019 Industry::Chemicals => "Chemicals",
2020 Industry::Conglomerates => "Conglomerates",
2021 Industry::ConsultingServices => "Consulting Services",
2022 Industry::ElectricalEquipmentAndParts => "Electrical Equipment & Parts",
2023 Industry::EngineeringAndConstruction => "Engineering & Construction",
2024 Industry::FarmAndHeavyConstructionMachinery => {
2025 "Farm & Heavy Construction Machinery"
2026 }
2027 Industry::IndustrialDistribution => "Industrial Distribution",
2028 Industry::InfrastructureOperations => "Infrastructure Operations",
2029 Industry::IntegratedFreightAndLogistics => "Integrated Freight & Logistics",
2030 Industry::ManufacturingDiversified => "Manufacturing - Diversified",
2031 Industry::MarinePortsAndServices => "Marine Ports & Services",
2032 Industry::MarineShipping => "Marine Shipping",
2033 Industry::MetalFabrication => "Metal Fabrication",
2034 Industry::PaperAndPaperProducts => "Paper & Paper Products",
2035 Industry::PollutionAndTreatmentControls => "Pollution & Treatment Controls",
2036 Industry::Railroads => "Railroads",
2037 Industry::RentalAndLeasingServices => "Rental & Leasing Services",
2038 Industry::SecurityAndProtectionServices => "Security & Protection Services",
2039 Industry::SpecialtyBusinessServices => "Specialty Business Services",
2040 Industry::SpecialtyChemicals => "Specialty Chemicals",
2041 Industry::SpecialtyIndustrialMachinery => "Specialty Industrial Machinery",
2042 Industry::StaffingAndEmploymentServices => "Staffing & Employment Services",
2043 Industry::ToolsAndAccessories => "Tools & Accessories",
2044 Industry::Trucking => "Trucking",
2045 Industry::WasteManagement => "Waste Management",
2046 Industry::RealEstateDevelopment => "Real Estate - Development",
2047 Industry::RealEstateDiversified => "Real Estate - Diversified",
2048 Industry::RealEstateServices => "Real Estate Services",
2049 Industry::ReitDiversified => "REIT - Diversified",
2050 Industry::ReitHealthcareFacilities => "REIT - Healthcare Facilities",
2051 Industry::ReitHotelAndMotel => "REIT - Hotel & Motel",
2052 Industry::ReitIndustrial => "REIT - Industrial",
2053 Industry::ReitMortgage => "REIT - Mortgage",
2054 Industry::ReitOffice => "REIT - Office",
2055 Industry::ReitResidential => "REIT - Residential",
2056 Industry::ReitRetail => "REIT - Retail",
2057 Industry::ReitSpecialty => "REIT - Specialty",
2058 Industry::CommunicationEquipment => "Communication Equipment",
2059 Industry::ComputerHardware => "Computer Hardware",
2060 Industry::ConsumerElectronics => "Consumer Electronics",
2061 Industry::DataAnalytics => "Data Analytics",
2062 Industry::ElectronicComponents => "Electronic Components",
2063 Industry::ElectronicsAndComputerDistribution => {
2064 "Electronics & Computer Distribution"
2065 }
2066 Industry::HardwareAndSoftwareDistribution => "Hardware & Software Distribution",
2067 Industry::InformationTechnologyServices => "Information Technology Services",
2068 Industry::InternetContentAndInformation => "Internet Content & Information",
2069 Industry::ScientificAndTechnicalInstruments => "Scientific & Technical Instruments",
2070 Industry::SemiconductorEquipmentAndMaterials => {
2071 "Semiconductor Equipment & Materials"
2072 }
2073 Industry::Semiconductors => "Semiconductors",
2074 Industry::SoftwareApplication => "Software - Application",
2075 Industry::SoftwareInfrastructure => "Software - Infrastructure",
2076 Industry::Broadcasting => "Broadcasting",
2077 Industry::Entertainment => "Entertainment",
2078 Industry::Publishing => "Publishing",
2079 Industry::TelecomServices => "Telecom Services",
2080 Industry::UtilitiesDiversified => "Utilities - Diversified",
2081 Industry::UtilitiesIndependentPowerProducers => {
2082 "Utilities - Independent Power Producers"
2083 }
2084 Industry::UtilitiesRegulatedElectric => "Utilities - Regulated Electric",
2085 Industry::UtilitiesRegulatedGas => "Utilities - Regulated Gas",
2086 Industry::UtilitiesRegulatedWater => "Utilities - Regulated Water",
2087 Industry::UtilitiesRenewable => "Utilities - Renewable",
2088 Industry::ClosedEndFundDebt => "Closed-End Fund - Debt",
2089 Industry::ClosedEndFundEquity => "Closed-End Fund - Equity",
2090 Industry::ClosedEndFundForeign => "Closed-End Fund - Foreign",
2091 Industry::ExchangeTradedFund => "Exchange Traded Fund",
2092 }
2093 }
2094 }
2095
2096 impl AsRef<str> for Industry {
2097 fn as_ref(&self) -> &str {
2099 self.as_slug()
2100 }
2101 }
2102
2103 impl From<Industry> for String {
2104 fn from(v: Industry) -> Self {
2106 v.screener_value().to_string()
2107 }
2108 }
2109}
2110
2111pub mod exchange_codes {
2128 #[non_exhaustive]
2130 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2131 pub enum ExchangeCode {
2132 Ase,
2135 Bts,
2137 Ncm,
2139 Ngm,
2141 Nms,
2143 Nyq,
2145 Pcx,
2147 Pnk,
2149 Nas,
2152 Asx,
2155 Bse,
2157 Hkg,
2159 Krx,
2161 Lse,
2163 Nsi,
2165 Shh,
2167 Shz,
2169 Tyo,
2171 Tor,
2173 Ger,
2175 }
2176
2177 impl ExchangeCode {
2178 pub fn as_str(self) -> &'static str {
2180 match self {
2181 ExchangeCode::Ase => "ASE",
2182 ExchangeCode::Bts => "BTS",
2183 ExchangeCode::Ncm => "NCM",
2184 ExchangeCode::Ngm => "NGM",
2185 ExchangeCode::Nms => "NMS",
2186 ExchangeCode::Nyq => "NYQ",
2187 ExchangeCode::Pcx => "PCX",
2188 ExchangeCode::Pnk => "PNK",
2189 ExchangeCode::Nas => "NAS",
2190 ExchangeCode::Asx => "ASX",
2191 ExchangeCode::Bse => "BSE",
2192 ExchangeCode::Hkg => "HKG",
2193 ExchangeCode::Krx => "KRX",
2194 ExchangeCode::Lse => "LSE",
2195 ExchangeCode::Nsi => "NSI",
2196 ExchangeCode::Shh => "SHH",
2197 ExchangeCode::Shz => "SHZ",
2198 ExchangeCode::Tyo => "TYO",
2199 ExchangeCode::Tor => "TOR",
2200 ExchangeCode::Ger => "GER",
2201 }
2202 }
2203 }
2204
2205 impl From<ExchangeCode> for String {
2206 fn from(v: ExchangeCode) -> Self {
2207 v.as_str().to_string()
2208 }
2209 }
2210}
2211
2212#[cfg(test)]
2213mod tests {
2214 use super::*;
2215
2216 #[test]
2217 fn test_interval_as_str() {
2218 assert_eq!(Interval::OneMinute.as_str(), "1m");
2219 assert_eq!(Interval::FiveMinutes.as_str(), "5m");
2220 assert_eq!(Interval::OneDay.as_str(), "1d");
2221 assert_eq!(Interval::OneWeek.as_str(), "1wk");
2222 }
2223
2224 #[test]
2225 fn test_time_range_as_str() {
2226 assert_eq!(TimeRange::OneDay.as_str(), "1d");
2227 assert_eq!(TimeRange::OneMonth.as_str(), "1mo");
2228 assert_eq!(TimeRange::OneYear.as_str(), "1y");
2229 assert_eq!(TimeRange::Max.as_str(), "max");
2230 }
2231
2232 #[test]
2233 fn test_statement_type_from_str_round_trips_as_str() {
2234 for statement in [
2235 StatementType::Income,
2236 StatementType::Balance,
2237 StatementType::CashFlow,
2238 ] {
2239 assert_eq!(statement.as_str().parse(), Ok(statement));
2240 }
2241 assert_eq!("INCOME-STATEMENT".parse(), Ok(StatementType::Income));
2242 assert_eq!("balance-sheet".parse(), Ok(StatementType::Balance));
2243 assert_eq!("cash".parse(), Ok(StatementType::CashFlow));
2244 assert_eq!("bogus".parse::<StatementType>(), Err(()));
2245 }
2246
2247 #[test]
2248 fn test_frequency_from_str_round_trips_as_str() {
2249 for frequency in [Frequency::Annual, Frequency::Quarterly] {
2250 assert_eq!(frequency.as_str().parse(), Ok(frequency));
2251 }
2252 assert_eq!("YEARLY".parse(), Ok(Frequency::Annual));
2253 assert_eq!("q".parse(), Ok(Frequency::Quarterly));
2254 assert_eq!("bogus".parse::<Frequency>(), Err(()));
2255 }
2256
2257 #[test]
2258 fn test_interval_from_str_round_trips_as_str() {
2259 for interval in [
2260 Interval::OneMinute,
2261 Interval::FiveMinutes,
2262 Interval::FifteenMinutes,
2263 Interval::ThirtyMinutes,
2264 Interval::OneHour,
2265 Interval::OneDay,
2266 Interval::OneWeek,
2267 Interval::OneMonth,
2268 Interval::ThreeMonths,
2269 ] {
2270 assert_eq!(interval.as_str().parse(), Ok(interval));
2271 }
2272 assert_eq!("1D".parse(), Ok(Interval::OneDay));
2273 assert_eq!(" 1d ".parse(), Ok(Interval::OneDay));
2274 assert_eq!("bogus".parse::<Interval>(), Err(()));
2275 }
2276
2277 #[test]
2278 fn test_time_range_from_str_round_trips_as_str() {
2279 for range in [
2280 TimeRange::OneDay,
2281 TimeRange::FiveDays,
2282 TimeRange::OneMonth,
2283 TimeRange::ThreeMonths,
2284 TimeRange::SixMonths,
2285 TimeRange::OneYear,
2286 TimeRange::TwoYears,
2287 TimeRange::FiveYears,
2288 TimeRange::TenYears,
2289 TimeRange::YearToDate,
2290 TimeRange::Max,
2291 ] {
2292 assert_eq!(range.as_str().parse(), Ok(range));
2293 }
2294 assert_eq!("1wk".parse(), Ok(TimeRange::FiveDays));
2295 assert_eq!("YTD".parse(), Ok(TimeRange::YearToDate));
2296 assert_eq!("bogus".parse::<TimeRange>(), Err(()));
2297 }
2298
2299 #[test]
2300 fn test_default_interval_buckets() {
2301 assert_eq!(TimeRange::OneDay.default_interval(), Interval::FiveMinutes);
2303 assert_eq!(
2304 TimeRange::FiveDays.default_interval(),
2305 Interval::FifteenMinutes
2306 );
2307 assert_eq!(TimeRange::OneMonth.default_interval(), Interval::OneDay);
2308 assert_eq!(TimeRange::OneYear.default_interval(), Interval::OneDay);
2309 assert_eq!(TimeRange::TwoYears.default_interval(), Interval::OneWeek);
2310 assert_eq!(TimeRange::Max.default_interval(), Interval::OneMonth);
2311 }
2312}