use serde::Deserialize;
use crate::api::ApiClient;
use crate::deserialize::{from_str, percent_f64};
use crate::error::{Error, Result};
#[derive(Debug, Deserialize, Clone, Default)]
struct GlobalQuote {
#[serde(rename = "01. symbol")]
symbol: String,
#[serde(rename = "02. open", deserialize_with = "from_str")]
open: f64,
#[serde(rename = "03. high", deserialize_with = "from_str")]
high: f64,
#[serde(rename = "04. low", deserialize_with = "from_str")]
low: f64,
#[serde(rename = "05. price", deserialize_with = "from_str")]
price: f64,
#[serde(rename = "06. volume", deserialize_with = "from_str")]
volume: u64,
#[serde(rename = "07. latest trading day")]
last_day: String,
#[serde(rename = "08. previous close", deserialize_with = "from_str")]
previous_close: f64,
#[serde(rename = "09. change", deserialize_with = "from_str")]
change: f64,
#[serde(rename = "10. change percent", deserialize_with = "percent_f64")]
change_percent: f64,
}
#[derive(Default)]
pub struct Quote {
global_quote: GlobalQuote,
}
impl Quote {
#[must_use]
pub fn open(&self) -> f64 {
self.global_quote.open
}
#[must_use]
pub fn high(&self) -> f64 {
self.global_quote.high
}
#[must_use]
pub fn low(&self) -> f64 {
self.global_quote.low
}
#[must_use]
pub fn price(&self) -> f64 {
self.global_quote.price
}
#[must_use]
pub fn volume(&self) -> u64 {
self.global_quote.volume
}
#[must_use]
pub fn previous(&self) -> f64 {
self.global_quote.previous_close
}
#[must_use]
pub fn change(&self) -> f64 {
self.global_quote.change
}
#[must_use]
pub fn change_percent(&self) -> f64 {
self.global_quote.change_percent
}
#[must_use]
pub fn last_trading(&self) -> &str {
&self.global_quote.last_day
}
#[must_use]
pub fn symbol(&self) -> &str {
&self.global_quote.symbol
}
}
#[derive(Debug, Deserialize)]
pub(crate) struct QuoteHelper {
#[serde(rename = "Global Quote")]
global_quote: Option<GlobalQuote>,
}
impl QuoteHelper {
fn convert(self) -> Result<Quote> {
let mut quote = Quote::default();
if self.global_quote.is_none() {
return Err(Error::EmptyResponse);
}
quote.global_quote = self.global_quote.unwrap();
Ok(quote)
}
}
pub struct QuoteBuilder<'a> {
api_client: &'a ApiClient,
symbol: &'a str,
}
impl<'a> QuoteBuilder<'a> {
crate::json_data_struct!(Quote, QuoteHelper);
#[must_use]
pub fn new(api_client: &'a ApiClient, symbol: &'a str) -> Self {
Self { api_client, symbol }
}
fn create_url(&self) -> String {
format!("query?function=GLOBAL_QUOTE&symbol={}", self.symbol)
}
}