use std::sync::Arc;
use crate::error::Result;
use crate::models::economic::{EconomicCategory, EconomicRelease, EconomicSeriesMatch};
use crate::providers::{Capability, Operation, ProviderSet};
domain_handle! {
pub struct EconomicIndicator { series_id, series_id }
cache: crate::models::economic::EconomicSeries
}
impl EconomicIndicator {
pub async fn series(&self) -> Result<crate::models::economic::EconomicSeries> {
fetch_via!(
self,
series_id,
ECONOMIC,
as_economic,
EconomicSeries,
fetch_economic_series,
crate::models::economic::EconomicSeries
)
}
pub async fn as_of(&self, date: &str) -> Result<crate::models::economic::EconomicSeries> {
let series_id: String = self.series_id().to_string();
let date = date.to_string();
let providers = Arc::clone(&self.providers);
self.cache
.get_or_try(format!("as_of\u{1f}{date}"), move || async move {
providers
.fetch(Capability::ECONOMIC, move |p| {
let (series_id, date) = (series_id.clone(), date.clone());
let p = p.clone();
async move {
p.as_economic()
.ok_or_else(|| p.not_supported(Operation::EconomicSeriesAsOf))?
.fetch_economic_series_as_of(&series_id, &date)
.await
}
})
.await
})
.await
}
}
pub struct EconomicCatalog {
providers: Arc<ProviderSet>,
}
impl EconomicCatalog {
pub(crate) fn with_providers(providers: Arc<ProviderSet>) -> Self {
Self { providers }
}
pub async fn search(&self, query: &str, limit: u32) -> Result<Vec<EconomicSeriesMatch>> {
let query = query.to_string();
dispatch_via!(
self,
ECONOMIC,
as_economic,
EconomicSearch,
fetch_economic_search,
[query],
&query,
limit
)
}
pub async fn categories(&self, parent_id: i64) -> Result<Vec<EconomicCategory>> {
dispatch_via!(
self,
ECONOMIC,
as_economic,
EconomicCategories,
fetch_economic_categories,
[],
parent_id
)
}
pub async fn releases(&self) -> Result<Vec<EconomicRelease>> {
dispatch_via!(
self,
ECONOMIC,
as_economic,
EconomicReleases,
fetch_economic_releases,
[]
)
}
}