use crate::api::APIRequestBuilder;
use crate::error::Error;
use crate::exchange_rate;
use crate::time_series;
use std::io::Read;
pub struct Client {
builder: APIRequestBuilder,
client: reqwest::blocking::Client,
}
impl Client {
pub fn new(key: &str) -> Client {
Client {
builder: APIRequestBuilder::new(key),
client: reqwest::blocking::Client::new(),
}
}
pub fn get_time_series_intraday(
&self,
symbol: &str,
interval: time_series::IntradayInterval,
) -> Result<time_series::TimeSeries, Error> {
let function = time_series::Function::IntraDay(interval);
self.get_time_series(&function, symbol, time_series::OutputSize::Compact)
}
pub fn get_time_series_intraday_full(
&self,
symbol: &str,
interval: time_series::IntradayInterval,
) -> Result<time_series::TimeSeries, Error> {
let function = time_series::Function::IntraDay(interval);
self.get_time_series(&function, symbol, time_series::OutputSize::Full)
}
pub fn get_time_series_daily(&self, symbol: &str) -> Result<time_series::TimeSeries, Error> {
let function = time_series::Function::Daily;
self.get_time_series(&function, symbol, time_series::OutputSize::Compact)
}
pub fn get_time_series_daily_full(
&self,
symbol: &str,
) -> Result<time_series::TimeSeries, Error> {
let function = time_series::Function::Daily;
self.get_time_series(&function, symbol, time_series::OutputSize::Full)
}
pub fn get_time_series_weekly(&self, symbol: &str) -> Result<time_series::TimeSeries, Error> {
let function = time_series::Function::Weekly;
self.get_time_series(&function, symbol, time_series::OutputSize::Compact)
}
pub fn get_time_series_weekly_full(
&self,
symbol: &str,
) -> Result<time_series::TimeSeries, Error> {
let function = time_series::Function::Weekly;
self.get_time_series(&function, symbol, time_series::OutputSize::Full)
}
pub fn get_time_series_monthly(&self, symbol: &str) -> Result<time_series::TimeSeries, Error> {
let function = time_series::Function::Monthly;
self.get_time_series(&function, symbol, time_series::OutputSize::Compact)
}
pub fn get_time_series_monthly_full(
&self,
symbol: &str,
) -> Result<time_series::TimeSeries, Error> {
let function = time_series::Function::Monthly;
self.get_time_series(&function, symbol, time_series::OutputSize::Full)
}
pub fn get_exchange_rate(
&self,
from_currency_code: &str,
to_currency_code: &str,
) -> Result<exchange_rate::ExchangeRate, Error> {
let function = "CURRENCY_EXCHANGE_RATE";
let params = vec![
("from_currency", from_currency_code),
("to_currency", to_currency_code),
];
let response = self.api_call(function, ¶ms)?;
let result = exchange_rate::parser::parse(response)?;
Ok(result)
}
pub fn get_tickers(&self, query: &str) -> Result<tickers::SearchResults, Error> {
let function = "SYMBOL_SEARCH";
let params = vec![("keywords", query)];
let request = self.builder.create(function, ¶ms);
let response = self.api_call(request)?;
let result = tickers::parser::parse(Some(query.to_string()), response)?;
Ok(result)
}
fn get_time_series(
&self,
function: &time_series::Function,
symbol: &str,
output_size: time_series::OutputSize,
) -> Result<time_series::TimeSeries, Error> {
let mut params = vec![("symbol", symbol), ("outputsize", output_size.to_string())];
if let time_series::Function::IntraDay(interval) = function {
params.push(("interval", interval.to_string()));
}
let response = self.api_call(function.into(), ¶ms)?;
let result = time_series::parser::parse(function, response)?;
Ok(result)
}
fn api_call(&self, function: &str, params: &[(&str, &str)]) -> Result<impl Read, Error> {
let request = self.builder.create(function, params);
let response = self.client.execute(request.into())?;
let status = response.status();
if status != reqwest::StatusCode::OK {
return Err(Error::ServerError(status.as_u16()));
}
Ok(response)
}
}