1use serde::{Deserialize, Serialize};
2
3#[non_exhaustive]
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
9#[serde(rename_all = "kebab-case")]
10pub enum Sector {
11 #[serde(alias = "tech")]
13 Technology,
14 #[serde(alias = "financials", alias = "financial")]
16 FinancialServices,
17 ConsumerCyclical,
19 #[serde(alias = "communication")]
21 CommunicationServices,
22 #[serde(alias = "health")]
24 Healthcare,
25 #[serde(alias = "industrial")]
27 Industrials,
28 ConsumerDefensive,
30 Energy,
32 #[serde(alias = "materials")]
34 BasicMaterials,
35 #[serde(alias = "realestate")]
37 RealEstate,
38 #[serde(alias = "utility")]
40 Utilities,
41}
42
43impl Sector {
44 pub fn as_api_path(&self) -> &'static str {
46 match self {
47 Sector::Technology => "technology",
48 Sector::FinancialServices => "financial-services",
49 Sector::ConsumerCyclical => "consumer-cyclical",
50 Sector::CommunicationServices => "communication-services",
51 Sector::Healthcare => "healthcare",
52 Sector::Industrials => "industrials",
53 Sector::ConsumerDefensive => "consumer-defensive",
54 Sector::Energy => "energy",
55 Sector::BasicMaterials => "basic-materials",
56 Sector::RealEstate => "real-estate",
57 Sector::Utilities => "utilities",
58 }
59 }
60
61 pub fn display_name(&self) -> &'static str {
63 match self {
64 Sector::Technology => "Technology",
65 Sector::FinancialServices => "Financial Services",
66 Sector::ConsumerCyclical => "Consumer Cyclical",
67 Sector::CommunicationServices => "Communication Services",
68 Sector::Healthcare => "Healthcare",
69 Sector::Industrials => "Industrials",
70 Sector::ConsumerDefensive => "Consumer Defensive",
71 Sector::Energy => "Energy",
72 Sector::BasicMaterials => "Basic Materials",
73 Sector::RealEstate => "Real Estate",
74 Sector::Utilities => "Utilities",
75 }
76 }
77
78 pub fn spdr_etf(&self) -> &'static str {
82 match self {
83 Sector::Technology => "XLK",
84 Sector::FinancialServices => "XLF",
85 Sector::ConsumerCyclical => "XLY",
86 Sector::CommunicationServices => "XLC",
87 Sector::Healthcare => "XLV",
88 Sector::Industrials => "XLI",
89 Sector::ConsumerDefensive => "XLP",
90 Sector::Energy => "XLE",
91 Sector::BasicMaterials => "XLB",
92 Sector::RealEstate => "XLRE",
93 Sector::Utilities => "XLU",
94 }
95 }
96
97 pub fn valid_types() -> &'static str {
99 "technology, financial-services, consumer-cyclical, communication-services, \
100 healthcare, industrials, consumer-defensive, energy, basic-materials, \
101 real-estate, utilities"
102 }
103
104 pub fn all() -> &'static [Sector] {
106 &[
107 Sector::Technology,
108 Sector::FinancialServices,
109 Sector::ConsumerCyclical,
110 Sector::CommunicationServices,
111 Sector::Healthcare,
112 Sector::Industrials,
113 Sector::ConsumerDefensive,
114 Sector::Energy,
115 Sector::BasicMaterials,
116 Sector::RealEstate,
117 Sector::Utilities,
118 ]
119 }
120}
121
122impl std::str::FromStr for Sector {
123 type Err = ();
124
125 fn from_str(s: &str) -> Result<Self, Self::Err> {
126 match s.to_lowercase().replace('_', "-").as_str() {
127 "technology" | "tech" => Ok(Sector::Technology),
128 "financial-services" | "financials" | "financial" => Ok(Sector::FinancialServices),
129 "consumer-cyclical" => Ok(Sector::ConsumerCyclical),
130 "communication-services" | "communication" => Ok(Sector::CommunicationServices),
131 "healthcare" | "health" => Ok(Sector::Healthcare),
132 "industrials" | "industrial" => Ok(Sector::Industrials),
133 "consumer-defensive" => Ok(Sector::ConsumerDefensive),
134 "energy" => Ok(Sector::Energy),
135 "basic-materials" | "materials" => Ok(Sector::BasicMaterials),
136 "real-estate" | "realestate" => Ok(Sector::RealEstate),
137 "utilities" | "utility" => Ok(Sector::Utilities),
138 _ => Err(()),
139 }
140 }
141}
142
143impl std::fmt::Display for Sector {
144 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
145 write!(f, "{}", self.display_name())
146 }
147}
148
149impl From<Sector> for String {
150 fn from(v: Sector) -> Self {
152 v.display_name().to_string()
153 }
154}