use serde::de::{self, Deserialize, Deserializer, Visitor, MapAccess};
use std::fmt;
pub struct SymbolFinnhub {
pub currency: String,
pub description: String,
pub display_symbol: String,
pub figi: String,
pub isin: String,
pub mic: String,
pub share_class_figi: String,
pub symbol: String,
pub symbol2: String,
pub typee: String,
}
impl<'de> Deserialize<'de> for SymbolFinnhub {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
enum Field {
Currency,
Description,
DisplaySymbol,
Figi,
Isin,
Mic,
ShareClassFigi,
Symbol,
Symbol2,
Typee,
}
impl<'de> Deserialize<'de> for Field {
fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
where
D: Deserializer<'de>,
{
struct FieldVisitor;
impl<'de> Visitor<'de> for FieldVisitor {
type Value = Field;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("field name")
}
fn visit_str<E>(self, value: &str) -> Result<Field, E>
where
E: de::Error,
{
match value {
"currency" => Ok(Field::Currency),
"description" => Ok(Field::Description),
"displaySymbol" => Ok(Field::DisplaySymbol),
"figi" => Ok(Field::Figi),
"isin" => Ok(Field::Isin),
"mic" => Ok(Field::Mic),
"shareClassFIGI" => Ok(Field::ShareClassFigi),
"symbol" => Ok(Field::Symbol),
"symbol2" => Ok(Field::Symbol2),
"type" => Ok(Field::Typee),
_ => Err(de::Error::unknown_field(value, FIELDS)),
}
}
}
deserializer.deserialize_identifier(FieldVisitor)
}
}
struct SymbolFinnhubVisitor;
impl<'de> Visitor<'de> for SymbolFinnhubVisitor {
type Value = SymbolFinnhub;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("struct SymbolFinnhub")
}
fn visit_map<V>(self, mut map: V) -> Result<SymbolFinnhub, V::Error>
where
V: MapAccess<'de>,
{
let mut currency = None;
let mut description = None;
let mut display_symbol = None;
let mut figi = None;
let mut isin = None;
let mut mic = None;
let mut share_class_figi = None;
let mut symbol = None;
let mut symbol2 = None;
let mut typee = None;
while let Some(key) = map.next_key()? {
match key {
Field::Currency => {
if currency.is_some() {
return Err(de::Error::duplicate_field("currency"));
}
currency = Some(map.next_value()?);
}
Field::Description => {
if description.is_some() {
return Err(de::Error::duplicate_field("description"));
}
description = Some(map.next_value()?);
}
Field::DisplaySymbol => {
if display_symbol.is_some() {
return Err(de::Error::duplicate_field("displaySymbol"));
}
display_symbol = Some(map.next_value()?);
}
Field::Figi => {
if figi.is_some() {
return Err(de::Error::duplicate_field("figi"));
}
figi = Some(map.next_value()?);
}
Field::Isin => {
if isin.is_some() {
return Err(de::Error::duplicate_field("isin"));
}
isin = Some(map.next_value()?);
}
Field::Mic => {
if mic.is_some() {
return Err(de::Error::duplicate_field("mic"));
}
mic = Some(map.next_value()?);
}
Field::ShareClassFigi => {
if share_class_figi.is_some() {
return Err(de::Error::duplicate_field("shareClassFIGI"));
}
share_class_figi = Some(map.next_value()?);
}
Field::Symbol => {
if symbol.is_some() {
return Err(de::Error::duplicate_field("symbol"));
}
symbol = Some(map.next_value()?);
}
Field::Symbol2 => {
if symbol2.is_some() {
return Err(de::Error::duplicate_field("symbol2"));
}
symbol2 = Some(map.next_value()?);
}
Field::Typee => {
if typee.is_some() {
return Err(de::Error::duplicate_field("type"));
}
typee = Some(map.next_value()?);
}
}
}
let currency = currency.ok_or_else(|| de::Error::missing_field("currency"))?;
let description = description.ok_or_else(|| de::Error::missing_field("description"))?;
let display_symbol = display_symbol.ok_or_else(|| de::Error::missing_field("displaySymbol"))?;
let figi = figi.ok_or_else(|| de::Error::missing_field("figi"))?;
let isin = isin.ok_or_else(|| de::Error::missing_field("isin"))?;
let mic = mic.ok_or_else(|| de::Error::missing_field("mic"))?;
let share_class_figi = share_class_figi.ok_or_else(|| de::Error::missing_field("shareClassFIGI"))?;
let symbol = symbol.ok_or_else(|| de::Error::missing_field("symbol"))?;
let symbol2 = symbol2.ok_or_else(|| de::Error::missing_field("symbol2"))?;
let typee = typee.ok_or_else(|| de::Error::missing_field("type"))?;
Ok(SymbolFinnhub {
currency,
description,
display_symbol,
figi,
isin,
mic,
share_class_figi,
symbol,
symbol2,
typee,
})
}
}
const FIELDS: &[&str] = &[
"currency",
"description",
"displaySymbol",
"figi",
"isin",
"mic",
"shareClassFIGI",
"symbol",
"symbol2",
"type",
];
deserializer.deserialize_struct("SymbolFinnhub", FIELDS, SymbolFinnhubVisitor)
}
}