/*
 * Binance Spot WebSocket Streams
 *
 * OpenAPI Specifications for the Binance Spot WebSocket Streams
 *
 * API documents:
 * - [Github web-socket-streams documentation file](https://github.com/binance/binance-spot-api-docs/blob/master/web-socket-streams.md)
 * - [General API information for web-socket-streams on website](https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams)
 *
 *
 * The version of the OpenAPI document: 1.0.0
 *
 *
 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 * https://openapi-generator.tech
 * Do not edit the class manually.
 */

#![allow(unused_imports)]
use crate::spot::websocket_streams::models;
use serde::{Deserialize, Deserializer, Serialize, de::Error};
use serde_json::Value;

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(try_from = "Value")]
pub enum SymbolFilters {
    #[serde(rename = "PRICE_FILTER")]
    PriceFilter(Box<models::PriceFilter>),
    #[serde(rename = "PERCENT_PRICE")]
    PercentPrice(Box<models::PercentPriceFilter>),
    #[serde(rename = "PERCENT_PRICE_BY_SIDE")]
    PercentPriceBySide(Box<models::PercentPriceBySideFilter>),
    #[serde(rename = "LOT_SIZE")]
    LotSize(Box<models::LotSizeFilter>),
    #[serde(rename = "MIN_NOTIONAL")]
    MinNotional(Box<models::MinNotionalFilter>),
    #[serde(rename = "NOTIONAL")]
    Notional(Box<models::NotionalFilter>),
    #[serde(rename = "ICEBERG_PARTS")]
    IcebergParts(Box<models::IcebergPartsFilter>),
    #[serde(rename = "MARKET_LOT_SIZE")]
    MarketLotSize(Box<models::MarketLotSizeFilter>),
    #[serde(rename = "MAX_NUM_ORDERS")]
    MaxNumOrders(Box<models::MaxNumOrdersFilter>),
    #[serde(rename = "MAX_NUM_ALGO_ORDERS")]
    MaxNumAlgoOrders(Box<models::MaxNumAlgoOrdersFilter>),
    #[serde(rename = "MAX_NUM_ICEBERG_ORDERS")]
    MaxNumIcebergOrders(Box<models::MaxNumIcebergOrdersFilter>),
    #[serde(rename = "MAX_POSITION")]
    MaxPosition(Box<models::MaxPositionFilter>),
    #[serde(rename = "TRAILING_DELTA")]
    TrailingDelta(Box<models::TrailingDeltaFilter>),
    #[serde(rename = "T_PLUS_SELL")]
    TPlusSell(Box<models::TPlusSellFilter>),
    #[serde(rename = "MAX_NUM_ORDER_LISTS")]
    MaxNumOrderLists(Box<models::MaxNumOrderListsFilter>),
    #[serde(rename = "MAX_NUM_ORDER_AMENDS")]
    MaxNumOrderAmends(Box<models::MaxNumOrderAmendsFilter>),
    Other(serde_json::Value),
}

impl Default for SymbolFilters {
    fn default() -> Self {
        Self::PriceFilter(Default::default())
    }
}

impl TryFrom<Value> for SymbolFilters {
    type Error = serde_json::Error;

    fn try_from(v: Value) -> Result<Self, Self::Error> {
        let tag = v
            .get("filterType")
            .and_then(Value::as_str)
            .ok_or_else(|| serde_json::Error::custom("missing field `filterType`"))?;

        match tag {
            "PRICE_FILTER" => {
                let payload = serde_json::from_value(v)?;
                Ok(SymbolFilters::PriceFilter(Box::new(payload)))
            }

            "PERCENT_PRICE" => {
                let payload = serde_json::from_value(v)?;
                Ok(SymbolFilters::PercentPrice(Box::new(payload)))
            }

            "PERCENT_PRICE_BY_SIDE" => {
                let payload = serde_json::from_value(v)?;
                Ok(SymbolFilters::PercentPriceBySide(Box::new(payload)))
            }

            "LOT_SIZE" => {
                let payload = serde_json::from_value(v)?;
                Ok(SymbolFilters::LotSize(Box::new(payload)))
            }

            "MIN_NOTIONAL" => {
                let payload = serde_json::from_value(v)?;
                Ok(SymbolFilters::MinNotional(Box::new(payload)))
            }

            "NOTIONAL" => {
                let payload = serde_json::from_value(v)?;
                Ok(SymbolFilters::Notional(Box::new(payload)))
            }

            "ICEBERG_PARTS" => {
                let payload = serde_json::from_value(v)?;
                Ok(SymbolFilters::IcebergParts(Box::new(payload)))
            }

            "MARKET_LOT_SIZE" => {
                let payload = serde_json::from_value(v)?;
                Ok(SymbolFilters::MarketLotSize(Box::new(payload)))
            }

            "MAX_NUM_ORDERS" => {
                let payload = serde_json::from_value(v)?;
                Ok(SymbolFilters::MaxNumOrders(Box::new(payload)))
            }

            "MAX_NUM_ALGO_ORDERS" => {
                let payload = serde_json::from_value(v)?;
                Ok(SymbolFilters::MaxNumAlgoOrders(Box::new(payload)))
            }

            "MAX_NUM_ICEBERG_ORDERS" => {
                let payload = serde_json::from_value(v)?;
                Ok(SymbolFilters::MaxNumIcebergOrders(Box::new(payload)))
            }

            "MAX_POSITION" => {
                let payload = serde_json::from_value(v)?;
                Ok(SymbolFilters::MaxPosition(Box::new(payload)))
            }

            "TRAILING_DELTA" => {
                let payload = serde_json::from_value(v)?;
                Ok(SymbolFilters::TrailingDelta(Box::new(payload)))
            }

            "T_PLUS_SELL" => {
                let payload = serde_json::from_value(v)?;
                Ok(SymbolFilters::TPlusSell(Box::new(payload)))
            }

            "MAX_NUM_ORDER_LISTS" => {
                let payload = serde_json::from_value(v)?;
                Ok(SymbolFilters::MaxNumOrderLists(Box::new(payload)))
            }

            "MAX_NUM_ORDER_AMENDS" => {
                let payload = serde_json::from_value(v)?;
                Ok(SymbolFilters::MaxNumOrderAmends(Box::new(payload)))
            }

            _ => Ok(SymbolFilters::Other(v)),
        }
    }
}
