use serde::{Deserialize, Deserializer, Serialize};
use super::FormattedValue;
fn deserialize_sector_weightings<'de, D>(
deserializer: D,
) -> Result<Option<SectorWeighting>, D::Error>
where
D: Deserializer<'de>,
{
let weightings: Option<Vec<SectorWeighting>> = Option::deserialize(deserializer)?;
Ok(weightings.map(|w| SectorWeighting::flatten(&w)))
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TopHoldings {
#[serde(default)]
pub max_age: Option<i64>,
#[serde(default)]
pub cash_position: Option<FormattedValue<f64>>,
#[serde(default)]
pub stock_position: Option<FormattedValue<f64>>,
#[serde(default)]
pub bond_position: Option<FormattedValue<f64>>,
#[serde(default)]
pub other_position: Option<FormattedValue<f64>>,
#[serde(default)]
pub preferred_position: Option<FormattedValue<f64>>,
#[serde(default)]
pub convertible_position: Option<FormattedValue<f64>>,
#[serde(default)]
pub holdings: Option<Vec<Holding>>,
#[serde(default)]
pub equity_holdings: Option<EquityHoldings>,
#[serde(default)]
pub bond_holdings: Option<serde_json::Value>,
#[serde(default)]
pub bond_ratings: Option<Vec<BondRating>>,
#[serde(default, deserialize_with = "deserialize_sector_weightings")]
#[serde(skip_serializing_if = "Option::is_none")]
pub sector_weightings: Option<SectorWeighting>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Holding {
#[serde(default)]
pub symbol: Option<String>,
#[serde(default)]
pub holding_name: Option<String>,
#[serde(default)]
pub holding_percent: Option<FormattedValue<f64>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct EquityHoldings {
#[serde(default)]
pub price_to_earnings: Option<FormattedValue<f64>>,
#[serde(default)]
pub price_to_book: Option<FormattedValue<f64>>,
#[serde(default)]
pub price_to_sales: Option<FormattedValue<f64>>,
#[serde(default)]
pub price_to_cashflow: Option<FormattedValue<f64>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BondRating {
#[serde(default)]
pub us_government: Option<FormattedValue<f64>>,
#[serde(default)]
pub aaa: Option<FormattedValue<f64>>,
#[serde(default)]
pub aa: Option<FormattedValue<f64>>,
#[serde(default)]
pub a: Option<FormattedValue<f64>>,
#[serde(default)]
pub bbb: Option<FormattedValue<f64>>,
#[serde(default)]
pub bb: Option<FormattedValue<f64>>,
#[serde(default)]
pub b: Option<FormattedValue<f64>>,
#[serde(default)]
pub below_b: Option<FormattedValue<f64>>,
#[serde(default)]
pub not_rated: Option<FormattedValue<f64>>,
#[serde(default)]
pub other: Option<FormattedValue<f64>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct SectorWeighting {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub realestate: Option<FormattedValue<f64>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub consumer_cyclical: Option<FormattedValue<f64>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub basic_materials: Option<FormattedValue<f64>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub consumer_defensive: Option<FormattedValue<f64>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub technology: Option<FormattedValue<f64>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub communication_services: Option<FormattedValue<f64>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub financial_services: Option<FormattedValue<f64>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub utilities: Option<FormattedValue<f64>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub industrials: Option<FormattedValue<f64>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub energy: Option<FormattedValue<f64>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub healthcare: Option<FormattedValue<f64>>,
}
impl SectorWeighting {
pub fn flatten(weightings: &[SectorWeighting]) -> SectorWeighting {
let mut result = SectorWeighting::default();
for w in weightings {
if w.realestate.is_some() {
result.realestate = w.realestate.clone();
}
if w.consumer_cyclical.is_some() {
result.consumer_cyclical = w.consumer_cyclical.clone();
}
if w.basic_materials.is_some() {
result.basic_materials = w.basic_materials.clone();
}
if w.consumer_defensive.is_some() {
result.consumer_defensive = w.consumer_defensive.clone();
}
if w.technology.is_some() {
result.technology = w.technology.clone();
}
if w.communication_services.is_some() {
result.communication_services = w.communication_services.clone();
}
if w.financial_services.is_some() {
result.financial_services = w.financial_services.clone();
}
if w.utilities.is_some() {
result.utilities = w.utilities.clone();
}
if w.industrials.is_some() {
result.industrials = w.industrials.clone();
}
if w.energy.is_some() {
result.energy = w.energy.clone();
}
if w.healthcare.is_some() {
result.healthcare = w.healthcare.clone();
}
}
result
}
}