use super::LookupQuote;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
struct RawLookupResponse {
finance: Option<RawFinanceResult>,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
struct RawFinanceResult {
result: Option<Vec<RawLookupResult>>,
#[allow(dead_code)] error: Option<serde_json::Value>,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
struct RawLookupResult {
documents: Option<Vec<LookupQuote>>,
start: Option<i32>,
count: Option<i32>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct LookupResults {
#[serde(default)]
pub quotes: Vec<LookupQuote>,
#[serde(skip_serializing_if = "Option::is_none")]
pub start: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub count: Option<i32>,
}
impl LookupResults {
pub fn from_json(value: serde_json::Value) -> Result<Self, serde_json::Error> {
Ok(Self::from_raw(serde_json::from_value(value)?))
}
pub(crate) fn from_slice(bytes: &[u8]) -> Result<Self, serde_json::Error> {
Ok(Self::from_raw(serde_json::from_slice(bytes)?))
}
fn from_raw(raw: RawLookupResponse) -> Self {
let (quotes, start, count) = raw
.finance
.and_then(|f| f.result)
.and_then(|r| r.into_iter().next())
.map(|result| {
(
result.documents.unwrap_or_default(),
result.start,
result.count,
)
})
.unwrap_or_default();
LookupResults {
quotes,
start,
count,
}
}
pub fn quotes(&self) -> &[LookupQuote] {
&self.quotes
}
pub fn result_count(&self) -> i32 {
self.count.unwrap_or(0)
}
pub fn is_empty(&self) -> bool {
self.quotes.is_empty()
}
}
#[cfg(feature = "dataframe")]
impl LookupResults {
pub fn to_dataframe(&self) -> ::polars::prelude::PolarsResult<::polars::prelude::DataFrame> {
LookupQuote::vec_to_dataframe(&self.quotes)
}
}