use crate::{
Client, Result,
codecs::TrueFalseFlag,
endpoints::{
EndpointSpec, QueryEncoder, QueryParameters,
metadata::{EndpointBounds, EndpointMetadata, GeographicAvailability},
},
responses::directory::{
ActivelyTradingSymbol, AvailableCountry, AvailableExchange, AvailableIndustry,
AvailableSector, CikEntry, CompanySymbol, EarningsTranscriptAvailability, EtfSymbol,
FinancialStatementSymbol, SymbolChange,
},
types::{Limit, Page},
};
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct AvailableExchangesQuery {
extended: Option<bool>,
}
impl AvailableExchangesQuery {
pub const fn new() -> Self {
Self { extended: None }
}
pub const fn with_extended(mut self, extended: bool) -> Self {
self.extended = Some(extended);
self
}
pub const fn extended(&self) -> Option<bool> {
self.extended
}
}
impl QueryParameters for AvailableExchangesQuery {
fn encode(&self, encoder: &mut QueryEncoder<'_>) {
encoder.optional("extended", self.extended);
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct CikListQuery {
page: Option<Page>,
limit: Option<Limit>,
}
impl CikListQuery {
pub const fn new() -> Self {
Self {
page: None,
limit: None,
}
}
pub const fn with_page(mut self, page: Page) -> Self {
self.page = Some(page);
self
}
pub const fn with_limit(mut self, limit: Limit) -> Self {
self.limit = Some(limit);
self
}
pub const fn page(&self) -> Option<Page> {
self.page
}
pub const fn limit(&self) -> Option<Limit> {
self.limit
}
}
impl QueryParameters for CikListQuery {
fn encode(&self, encoder: &mut QueryEncoder<'_>) {
encoder.optional("page", self.page);
encoder.optional("limit", self.limit);
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct SymbolChangesQuery {
invalid: Option<TrueFalseFlag>,
limit: Option<Limit>,
}
impl SymbolChangesQuery {
pub const fn new() -> Self {
Self {
invalid: None,
limit: None,
}
}
pub const fn with_invalid(mut self, invalid: TrueFalseFlag) -> Self {
self.invalid = Some(invalid);
self
}
pub const fn with_limit(mut self, limit: Limit) -> Self {
self.limit = Some(limit);
self
}
pub const fn invalid(&self) -> Option<TrueFalseFlag> {
self.invalid
}
pub const fn limit(&self) -> Option<Limit> {
self.limit
}
}
impl QueryParameters for SymbolChangesQuery {
fn encode(&self, encoder: &mut QueryEncoder<'_>) {
encoder.optional("invalid", self.invalid);
encoder.optional("limit", self.limit);
}
}
const WORLDWIDE: EndpointMetadata =
EndpointMetadata::new().with_geography(GeographicAvailability::Worldwide);
const US_ONLY: EndpointMetadata =
EndpointMetadata::new().with_geography(GeographicAvailability::UsOnly);
const CIK_LIST: EndpointMetadata =
US_ONLY.with_bounds(EndpointBounds::new().with_response_rows(10_000));
pub fn company_symbols() -> EndpointSpec<(), Vec<CompanySymbol>> {
EndpointSpec::get("stock-list", "stock-list", ()).with_metadata(WORLDWIDE)
}
pub fn financial_statement_symbols() -> EndpointSpec<(), Vec<FinancialStatementSymbol>> {
EndpointSpec::get(
"financial-statement-symbol-list",
"financial-statement-symbol-list",
(),
)
.with_metadata(WORLDWIDE)
}
pub fn cik_list(query: CikListQuery) -> EndpointSpec<CikListQuery, Vec<CikEntry>> {
EndpointSpec::get("cik-list", "cik-list", query).with_metadata(CIK_LIST)
}
pub fn symbol_changes(
query: SymbolChangesQuery,
) -> EndpointSpec<SymbolChangesQuery, Vec<SymbolChange>> {
EndpointSpec::get("symbol-change", "symbol-change", query).with_metadata(US_ONLY)
}
pub fn etf_symbols() -> EndpointSpec<(), Vec<EtfSymbol>> {
EndpointSpec::get("etf-list", "etf-list", ()).with_metadata(WORLDWIDE)
}
pub fn actively_trading() -> EndpointSpec<(), Vec<ActivelyTradingSymbol>> {
EndpointSpec::get("actively-trading-list", "actively-trading-list", ()).with_metadata(WORLDWIDE)
}
pub fn earnings_transcript_list() -> EndpointSpec<(), Vec<EarningsTranscriptAvailability>> {
EndpointSpec::get("earnings-transcript-list", "earnings-transcript-list", ())
.with_metadata(US_ONLY)
}
pub fn available_exchanges(
query: AvailableExchangesQuery,
) -> EndpointSpec<AvailableExchangesQuery, Vec<AvailableExchange>> {
EndpointSpec::get("available-exchanges", "available-exchanges", query).with_metadata(WORLDWIDE)
}
pub fn available_sectors() -> EndpointSpec<(), Vec<AvailableSector>> {
EndpointSpec::get("available-sectors", "available-sectors", ())
}
pub fn available_industries() -> EndpointSpec<(), Vec<AvailableIndustry>> {
EndpointSpec::get("available-industries", "available-industries", ())
}
pub fn available_countries() -> EndpointSpec<(), Vec<AvailableCountry>> {
EndpointSpec::get("available-countries", "available-countries", ())
}
impl Client {
pub async fn company_symbols(&self) -> Result<Vec<CompanySymbol>> {
self.execute(&company_symbols()).await
}
pub async fn financial_statement_symbols(&self) -> Result<Vec<FinancialStatementSymbol>> {
self.execute(&financial_statement_symbols()).await
}
pub async fn cik_list(&self, query: CikListQuery) -> Result<Vec<CikEntry>> {
self.execute(&cik_list(query)).await
}
pub async fn symbol_changes(&self, query: SymbolChangesQuery) -> Result<Vec<SymbolChange>> {
self.execute(&symbol_changes(query)).await
}
pub async fn etf_symbols(&self) -> Result<Vec<EtfSymbol>> {
self.execute(&etf_symbols()).await
}
pub async fn actively_trading(&self) -> Result<Vec<ActivelyTradingSymbol>> {
self.execute(&actively_trading()).await
}
pub async fn earnings_transcript_list(&self) -> Result<Vec<EarningsTranscriptAvailability>> {
self.execute(&earnings_transcript_list()).await
}
pub async fn available_exchanges(
&self,
query: AvailableExchangesQuery,
) -> Result<Vec<AvailableExchange>> {
self.execute(&available_exchanges(query)).await
}
pub async fn available_sectors(&self) -> Result<Vec<AvailableSector>> {
self.execute(&available_sectors()).await
}
pub async fn available_industries(&self) -> Result<Vec<AvailableIndustry>> {
self.execute(&available_industries()).await
}
pub async fn available_countries(&self) -> Result<Vec<AvailableCountry>> {
self.execute(&available_countries()).await
}
}