use crate::models::chart::spark::Spark;
use crate::models::chart::{CapitalGain, Chart, Dividend, Split};
use crate::models::corporate::news::News;
use crate::models::corporate::recommendation::Recommendation;
use crate::models::corporate::transcript::{Transcript, TranscriptWithMeta};
use crate::models::discovery::lookup::{LookupQuote, LookupResults};
use crate::models::discovery::search::{
SearchNews, SearchNewsList, SearchQuote, SearchQuotes, SearchResults,
};
use crate::models::format::Format;
use crate::models::fundamentals::FinancialStatement;
use crate::models::market::industries::IndustryData;
use crate::models::market::market_summary::MarketSummaryQuote;
use crate::models::market::sectors::SectorData;
use crate::models::options::Options;
use crate::models::quote::{
AssetProfile, CalendarEvents, CompanyOfficer, DefaultKeyStatistics, Earnings, EarningsHistory,
EarningsTrend, EquityPerformance, FinancialData, FundOwnership, FundPerformance, FundProfile,
IndexTrend, IndustryTrend, InsiderHolders, InsiderTransactions, InstitutionOwnership,
MajorHoldersBreakdown, NetSharePurchaseActivity, Price, Quote, QuoteTypeData,
RecommendationTrend, SecFilings, SectorTrend, SummaryDetail, SummaryProfile, TopHoldings,
UpgradeDowngradeHistory,
};
pub trait Translatable {
fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
let _ = visit;
}
fn after_translate(&mut self) {}
}
fn visit_opt(field: &mut Option<String>, visit: &mut dyn FnMut(&mut String)) {
if let Some(value) = field {
visit(value);
}
}
impl<T: Translatable> Translatable for Option<T> {
fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
if let Some(value) = self {
value.visit_translatable(visit);
}
}
fn after_translate(&mut self) {
if let Some(value) = self {
value.after_translate();
}
}
}
impl<T: Translatable> Translatable for Vec<T> {
fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
for value in self {
value.visit_translatable(visit);
}
}
fn after_translate(&mut self) {
for value in self {
value.after_translate();
}
}
}
impl<F: Format> Translatable for Quote<F> {
fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
visit_opt(&mut self.short_name, visit);
visit_opt(&mut self.long_name, visit);
visit_opt(&mut self.sector_disp, visit);
visit_opt(&mut self.industry_disp, visit);
visit_opt(&mut self.long_business_summary, visit);
}
}
impl<F: Format> Translatable for Price<F> {
fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
visit_opt(&mut self.short_name, visit);
visit_opt(&mut self.long_name, visit);
}
}
impl Translatable for CompanyOfficer {
fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
visit_opt(&mut self.title, visit);
}
}
impl Translatable for AssetProfile {
fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
visit_opt(&mut self.sector_disp, visit);
visit_opt(&mut self.industry_disp, visit);
visit_opt(&mut self.long_business_summary, visit);
self.company_officers.visit_translatable(visit);
}
}
impl Translatable for SummaryProfile {
fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
visit_opt(&mut self.sector_disp, visit);
visit_opt(&mut self.industry_disp, visit);
visit_opt(&mut self.long_business_summary, visit);
}
}
impl Translatable for QuoteTypeData {
fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
visit_opt(&mut self.short_name, visit);
visit_opt(&mut self.long_name, visit);
}
}
impl Translatable for News {
fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
visit(&mut self.title);
}
}
impl Translatable for SearchNews {
fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
visit_opt(&mut self.title, visit);
}
}
impl Translatable for SearchQuote {
fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
visit_opt(&mut self.short_name, visit);
visit_opt(&mut self.long_name, visit);
visit_opt(&mut self.type_disp, visit);
visit_opt(&mut self.exch_disp, visit);
visit_opt(&mut self.sector_disp, visit);
visit_opt(&mut self.industry_disp, visit);
}
}
impl Translatable for SearchQuotes {
fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
self.0.visit_translatable(visit);
}
}
impl Translatable for SearchNewsList {
fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
self.0.visit_translatable(visit);
}
}
impl Translatable for SearchResults {
fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
self.quotes.visit_translatable(visit);
self.news.visit_translatable(visit);
}
}
impl Translatable for LookupQuote {
fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
visit_opt(&mut self.short_name, visit);
visit_opt(&mut self.long_name, visit);
visit_opt(&mut self.type_disp, visit);
visit_opt(&mut self.exch_disp, visit);
visit_opt(&mut self.sector, visit);
visit_opt(&mut self.industry, visit);
}
}
impl Translatable for LookupResults {
fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
self.quotes.visit_translatable(visit);
}
}
impl Translatable for MarketSummaryQuote {
fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
visit_opt(&mut self.short_name, visit);
visit_opt(&mut self.full_exchange_name, visit);
}
}
impl Translatable for SectorData {
fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
visit(&mut self.name);
if let Some(overview) = &mut self.overview {
visit_opt(&mut overview.description, visit);
}
for industry in &mut self.industries {
visit(&mut industry.name);
}
}
}
impl Translatable for IndustryData {
fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
visit(&mut self.name);
visit_opt(&mut self.sector_name, visit);
if let Some(overview) = &mut self.overview {
visit_opt(&mut overview.description, visit);
}
}
}
impl Translatable for Transcript {
fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
visit(&mut self.transcript_metadata.title);
for mapping in &mut self.transcript_content.speaker_mapping {
visit_opt(&mut mapping.speaker_data.role, visit);
}
if let Some(data) = &mut self.transcript_content.transcript {
if data.paragraphs.is_empty() {
visit(&mut data.text);
} else {
for paragraph in &mut data.paragraphs {
visit(&mut paragraph.text);
}
}
}
}
fn after_translate(&mut self) {
if let Some(data) = &mut self.transcript_content.transcript
&& !data.paragraphs.is_empty()
{
data.text = data
.paragraphs
.iter()
.map(|p| p.text.as_str())
.collect::<Vec<_>>()
.join("\n");
}
}
}
impl Translatable for TranscriptWithMeta {
fn visit_translatable(&mut self, visit: &mut dyn FnMut(&mut String)) {
visit(&mut self.title);
self.transcript.visit_translatable(visit);
}
fn after_translate(&mut self) {
self.transcript.after_translate();
}
}
macro_rules! not_translatable {
($($ty:ty),* $(,)?) => {
$(impl Translatable for $ty {})*
};
}
not_translatable!(
SummaryDetail,
FinancialData,
DefaultKeyStatistics,
CalendarEvents,
Earnings,
EarningsTrend,
EarningsHistory,
RecommendationTrend,
InsiderHolders,
InsiderTransactions,
InstitutionOwnership,
FundOwnership,
MajorHoldersBreakdown,
NetSharePurchaseActivity,
SecFilings,
UpgradeDowngradeHistory,
FundPerformance,
FundProfile,
TopHoldings,
IndexTrend,
IndustryTrend,
SectorTrend,
EquityPerformance,
Chart,
Spark,
Dividend,
Split,
CapitalGain,
FinancialStatement,
Recommendation,
Options,
);
#[cfg(feature = "indicators")]
not_translatable!(crate::indicators::IndicatorsSummary);