finance_query/translation/
translatable.rs1use crate::models::chart::spark::Spark;
8use crate::models::chart::{CapitalGain, Chart, Dividend, Split};
9use crate::models::corporate::news::News;
10use crate::models::corporate::recommendation::Recommendation;
11use crate::models::corporate::transcript::{Transcript, TranscriptWithMeta};
12use crate::models::discovery::lookup::{LookupQuote, LookupResults};
13use crate::models::discovery::search::{
14 SearchNews, SearchNewsList, SearchQuote, SearchQuotes, SearchResults,
15};
16use crate::models::format::Format;
17use crate::models::fundamentals::FinancialStatement;
18use crate::models::market::industries::IndustryData;
19use crate::models::market::market_summary::MarketSummaryQuote;
20use crate::models::market::sectors::SectorData;
21use crate::models::options::Options;
22use crate::models::quote::{
23 AssetProfile, CalendarEvents, CompanyOfficer, DefaultKeyStatistics, Earnings, EarningsHistory,
24 EarningsTrend, EquityPerformance, FinancialData, FundOwnership, FundPerformance, FundProfile,
25 IndexTrend, IndustryTrend, InsiderHolders, InsiderTransactions, InstitutionOwnership,
26 MajorHoldersBreakdown, NetSharePurchaseActivity, Price, Quote, QuoteTypeData,
27 RecommendationTrend, SecFilings, SectorTrend, SummaryDetail, SummaryProfile, TopHoldings,
28 UpgradeDowngradeHistory,
29};
30
31pub trait Translatable {
40 fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
42 let _ = visit;
43 }
44
45 fn after_translate(&mut self) {}
48}
49
50fn visit_opt(field: &mut Option<String>, visit: &mut dyn FnMut(&mut String)) {
51 if let Some(value) = field {
52 visit(value);
53 }
54}
55
56impl<T: Translatable> Translatable for Option<T> {
57 fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
58 if let Some(value) = self {
59 value.visit_translatable(visit);
60 }
61 }
62 fn after_translate(&mut self) {
63 if let Some(value) = self {
64 value.after_translate();
65 }
66 }
67}
68
69impl<T: Translatable> Translatable for Vec<T> {
70 fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
71 for value in self {
72 value.visit_translatable(visit);
73 }
74 }
75 fn after_translate(&mut self) {
76 for value in self {
77 value.after_translate();
78 }
79 }
80}
81
82impl<F: Format> Translatable for Quote<F> {
83 fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
84 visit_opt(&mut self.short_name, visit);
85 visit_opt(&mut self.long_name, visit);
86 visit_opt(&mut self.sector_disp, visit);
87 visit_opt(&mut self.industry_disp, visit);
88 visit_opt(&mut self.long_business_summary, visit);
89 }
90}
91
92impl<F: Format> Translatable for Price<F> {
93 fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
94 visit_opt(&mut self.short_name, visit);
95 visit_opt(&mut self.long_name, visit);
96 }
97}
98
99impl Translatable for CompanyOfficer {
100 fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
101 visit_opt(&mut self.title, visit);
102 }
103}
104
105impl Translatable for AssetProfile {
106 fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
107 visit_opt(&mut self.sector_disp, visit);
108 visit_opt(&mut self.industry_disp, visit);
109 visit_opt(&mut self.long_business_summary, visit);
110 self.company_officers.visit_translatable(visit);
111 }
112}
113
114impl Translatable for SummaryProfile {
115 fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
116 visit_opt(&mut self.sector_disp, visit);
117 visit_opt(&mut self.industry_disp, visit);
118 visit_opt(&mut self.long_business_summary, visit);
119 }
120}
121
122impl Translatable for QuoteTypeData {
123 fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
124 visit_opt(&mut self.short_name, visit);
125 visit_opt(&mut self.long_name, visit);
126 }
127}
128
129impl Translatable for News {
130 fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
131 visit(&mut self.title);
132 }
133}
134
135impl Translatable for SearchNews {
136 fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
137 visit_opt(&mut self.title, visit);
138 }
139}
140
141impl Translatable for SearchQuote {
142 fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
143 visit_opt(&mut self.short_name, visit);
144 visit_opt(&mut self.long_name, visit);
145 visit_opt(&mut self.type_disp, visit);
146 visit_opt(&mut self.exch_disp, visit);
147 visit_opt(&mut self.sector_disp, visit);
148 visit_opt(&mut self.industry_disp, visit);
149 }
150}
151
152impl Translatable for SearchQuotes {
153 fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
154 self.0.visit_translatable(visit);
155 }
156}
157
158impl Translatable for SearchNewsList {
159 fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
160 self.0.visit_translatable(visit);
161 }
162}
163
164impl Translatable for SearchResults {
165 fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
166 self.quotes.visit_translatable(visit);
167 self.news.visit_translatable(visit);
168 }
169}
170
171impl Translatable for LookupQuote {
172 fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
173 visit_opt(&mut self.short_name, visit);
174 visit_opt(&mut self.long_name, visit);
175 visit_opt(&mut self.type_disp, visit);
176 visit_opt(&mut self.exch_disp, visit);
177 visit_opt(&mut self.sector, visit);
178 visit_opt(&mut self.industry, visit);
179 }
180}
181
182impl Translatable for LookupResults {
183 fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
184 self.quotes.visit_translatable(visit);
185 }
186}
187
188impl Translatable for MarketSummaryQuote {
189 fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
190 visit_opt(&mut self.short_name, visit);
191 visit_opt(&mut self.full_exchange_name, visit);
192 }
193}
194
195impl Translatable for SectorData {
196 fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
197 visit(&mut self.name);
198 if let Some(overview) = &mut self.overview {
199 visit_opt(&mut overview.description, visit);
200 }
201 for industry in &mut self.industries {
202 visit(&mut industry.name);
203 }
204 }
205}
206
207impl Translatable for IndustryData {
208 fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
209 visit(&mut self.name);
210 visit_opt(&mut self.sector_name, visit);
211 if let Some(overview) = &mut self.overview {
212 visit_opt(&mut overview.description, visit);
213 }
214 }
215}
216
217impl Translatable for Transcript {
218 fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
225 visit(&mut self.transcript_metadata.title);
226 for mapping in &mut self.transcript_content.speaker_mapping {
227 visit_opt(&mut mapping.speaker_data.role, visit);
228 }
229 if let Some(data) = &mut self.transcript_content.transcript {
230 if data.paragraphs.is_empty() {
231 visit(&mut data.text);
232 } else {
233 for paragraph in &mut data.paragraphs {
234 visit(&mut paragraph.text);
235 }
236 }
237 }
238 }
239
240 fn after_translate(&mut self) {
241 if let Some(data) = &mut self.transcript_content.transcript
242 && !data.paragraphs.is_empty()
243 {
244 data.text = data
245 .paragraphs
246 .iter()
247 .map(|p| p.text.as_str())
248 .collect::<Vec<_>>()
249 .join("\n");
250 }
251 }
252}
253
254impl Translatable for TranscriptWithMeta {
255 fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
256 visit(&mut self.title);
257 self.transcript.visit_translatable(visit);
258 }
259
260 fn after_translate(&mut self) {
261 self.transcript.after_translate();
262 }
263}
264
265macro_rules! not_translatable {
268 ($($ty:ty),* $(,)?) => {
269 $(impl Translatable for $ty {})*
270 };
271}
272
273not_translatable!(
274 SummaryDetail,
275 FinancialData,
276 DefaultKeyStatistics,
277 CalendarEvents,
278 Earnings,
279 EarningsTrend,
280 EarningsHistory,
281 RecommendationTrend,
282 InsiderHolders,
283 InsiderTransactions,
284 InstitutionOwnership,
285 FundOwnership,
286 MajorHoldersBreakdown,
287 NetSharePurchaseActivity,
288 SecFilings,
289 UpgradeDowngradeHistory,
290 FundPerformance,
291 FundProfile,
292 TopHoldings,
293 IndexTrend,
294 IndustryTrend,
295 SectorTrend,
296 EquityPerformance,
297 Chart,
298 Spark,
299 Dividend,
300 Split,
301 CapitalGain,
302 FinancialStatement,
303 Recommendation,
304 Options,
305);
306
307#[cfg(feature = "indicators")]
308not_translatable!(crate::indicators::IndicatorsSummary);