#![allow(dead_code)]
use std::str::FromStr;
use serde::{Deserialize, Deserializer, Serializer, de::Error as _, ser::Error as _};
use time::{Date, OffsetDateTime};
pub(crate) mod date_opt {
use super::*;
pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<Option<Date>, D::Error>
where
D: Deserializer<'de>,
{
let value = String::deserialize(deserializer)?;
if !value.is_empty() {
let datetime = Date::parse(
&value,
time::macros::format_description!("[year]-[month]-[day]"),
)
.map_err(D::Error::custom)?;
Ok(Some(datetime))
} else {
Ok(None)
}
}
pub(crate) fn serialize<S>(datetime: &Option<Date>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match datetime {
Some(date) => serializer.serialize_str(
&date
.format(time::macros::format_description!("[year]-[month]-[day]"))
.unwrap(),
),
None => serializer.serialize_none(),
}
}
}
pub(crate) mod timestamp {
use super::*;
pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<OffsetDateTime, D::Error>
where
D: Deserializer<'de>,
{
let value = String::deserialize(deserializer)?;
let value = value.parse::<i64>().map_err(D::Error::custom)?;
OffsetDateTime::from_unix_timestamp(value).map_err(D::Error::custom)
}
pub(crate) fn serialize<S>(datetime: &OffsetDateTime, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.collect_str(&datetime.unix_timestamp())
}
}
pub(crate) mod timestamp_opt {
use super::*;
pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<Option<OffsetDateTime>, D::Error>
where
D: Deserializer<'de>,
{
let Some(value) = <Option<String>>::deserialize(deserializer)? else {
return Ok(None);
};
if value.is_empty() {
return Ok(None);
}
let value = value.parse::<i64>().map_err(D::Error::custom)?;
if value != 0 {
let datetime = OffsetDateTime::from_unix_timestamp(value).map_err(D::Error::custom)?;
Ok(Some(datetime))
} else {
Ok(None)
}
}
pub(crate) fn serialize<S>(
datetime: &Option<OffsetDateTime>,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match datetime {
Some(datetime) => serializer.collect_str(&datetime.unix_timestamp()),
None => serializer.serialize_none(),
}
}
}
pub(crate) mod rfc3339_opt {
use super::*;
pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<Option<OffsetDateTime>, D::Error>
where
D: Deserializer<'de>,
{
let Some(value) = <Option<String>>::deserialize(deserializer)? else {
return Ok(None);
};
if value.is_empty() {
return Ok(None);
}
let datetime =
OffsetDateTime::parse(&value, &time::format_description::well_known::Rfc3339)
.map_err(D::Error::custom)?;
Ok(Some(datetime))
}
pub(crate) fn serialize<S>(
datetime: &Option<OffsetDateTime>,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match datetime {
Some(datetime) => serializer.collect_str(
&datetime
.format(&time::format_description::well_known::Rfc3339)
.map_err(S::Error::custom)?,
),
None => serializer.serialize_none(),
}
}
}
pub(crate) mod risk_level {
use super::*;
pub(crate) fn serialize<S>(value: &i32, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.collect_str(value)
}
pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<i32, D::Error>
where
D: Deserializer<'de>,
{
let value = String::deserialize(deserializer)?;
if !value.is_empty() {
Ok(value
.parse::<i32>()
.map_err(|err| D::Error::custom(err.to_string()))?)
} else {
Ok(0)
}
}
}
pub(crate) mod decimal_empty_is_0 {
use rust_decimal::Decimal;
use super::*;
pub(crate) fn serialize<S>(value: &Decimal, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.collect_str(&value)
}
pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<Decimal, D::Error>
where
D: Deserializer<'de>,
{
let value = String::deserialize(deserializer)?;
if !value.is_empty() {
let n = value.parse::<Decimal>().map_err(D::Error::custom)?;
Ok(n)
} else {
Ok(Decimal::ZERO)
}
}
}
pub(crate) mod decimal_opt_empty_is_none {
use rust_decimal::Decimal;
use super::*;
pub(crate) fn serialize<S>(value: &Option<Decimal>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match value {
Some(value) => serializer.collect_str(&value),
_ => serializer.serialize_none(),
}
}
pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<Option<Decimal>, D::Error>
where
D: Deserializer<'de>,
{
let value = String::deserialize(deserializer)?;
if !value.is_empty() {
let n = value.parse::<Decimal>().map_err(D::Error::custom)?;
Ok(Some(n))
} else {
Ok(None)
}
}
}
pub(crate) mod decimal_opt_str_is_none {
use rust_decimal::Decimal;
use super::*;
pub(crate) fn serialize<S>(value: &Option<Decimal>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match value {
Some(value) => serializer.collect_str(&value),
_ => serializer.serialize_none(),
}
}
pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<Option<Decimal>, D::Error>
where
D: Deserializer<'de>,
{
let value = String::deserialize(deserializer)?;
if value.is_empty() {
return Ok(None);
}
Ok(value.parse::<Decimal>().ok()) }
}
pub(crate) mod decimal_opt_0_is_none {
use rust_decimal::Decimal;
use super::*;
pub(crate) fn serialize<S>(value: &Option<Decimal>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match value {
Some(value) => serializer.collect_str(&value),
_ => serializer.serialize_none(),
}
}
pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<Option<Decimal>, D::Error>
where
D: Deserializer<'de>,
{
let value = String::deserialize(deserializer)?;
let n = value.parse::<Decimal>().map_err(D::Error::custom)?;
if !n.is_zero() { Ok(Some(n)) } else { Ok(None) }
}
}
pub(crate) mod trigger_status {
use super::*;
use crate::trade::TriggerStatus;
pub(crate) fn serialize<S>(
value: &Option<TriggerStatus>,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match value {
Some(value) => serializer.collect_str(value),
None => serializer.serialize_none(),
}
}
pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<Option<TriggerStatus>, D::Error>
where
D: Deserializer<'de>,
{
let value = String::deserialize(deserializer)?;
match value.as_str() {
"NOT_USED" => Ok(None),
_ => Ok(Some(
TriggerStatus::from_str(value.as_str()).unwrap_or_default(),
)),
}
}
}
pub(crate) mod outside_rth {
use super::*;
use crate::trade::OutsideRTH;
pub(crate) fn serialize<S>(value: &Option<OutsideRTH>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match value {
Some(value) => serializer.collect_str(value),
None => serializer.serialize_none(),
}
}
pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<Option<OutsideRTH>, D::Error>
where
D: Deserializer<'de>,
{
let value = String::deserialize(deserializer)?;
match value.as_str() {
"UnknownOutsideRth" => Ok(None),
_ => Ok(Some(
OutsideRTH::from_str(value.as_str()).unwrap_or_default(),
)),
}
}
}
pub(crate) mod symbol_opt {
use super::*;
pub(crate) fn serialize<S>(value: &Option<String>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match value {
Some(value) => serializer.serialize_str(value),
None => serializer.serialize_none(),
}
}
pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
where
D: Deserializer<'de>,
{
match <Option<String>>::deserialize(deserializer)? {
Some(value) if value.is_empty() => Ok(None),
Some(value) => Ok(Some(value)),
_ => Ok(None),
}
}
}
pub(crate) mod int64_str {
use super::*;
pub(crate) fn serialize<S>(value: &i64, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.collect_str(value)
}
pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<i64, D::Error>
where
D: Deserializer<'de>,
{
let value = String::deserialize(deserializer)?;
Ok(value.parse::<i64>().unwrap_or_default())
}
}
pub(crate) mod int64_str_empty_is_none {
use super::*;
pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<Option<i64>, D::Error>
where
D: Deserializer<'de>,
{
let value = String::deserialize(deserializer)?;
if !value.is_empty() {
Ok(Some(
value
.parse::<i64>()
.map_err(|err| D::Error::custom(err.to_string()))?,
))
} else {
Ok(None)
}
}
}
pub(crate) fn deserialize_timestamp<'de, D>(deserializer: D) -> Result<OffsetDateTime, D::Error>
where
D: Deserializer<'de>,
{
timestamp::deserialize(deserializer)
}
pub(crate) mod int32_opt_0_is_none {
use super::*;
pub(crate) fn serialize<S>(value: &Option<i32>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match value {
Some(value) => serializer.serialize_i32(*value),
_ => serializer.serialize_none(),
}
}
pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<Option<i32>, D::Error>
where
D: Deserializer<'de>,
{
let value = i32::deserialize(deserializer)?;
if value == 0 {
Ok(None)
} else {
Ok(Some(value))
}
}
}
pub(crate) fn deserialize_string_or_int_as_string<'de, D>(d: D) -> Result<String, D::Error>
where
D: serde::Deserializer<'de>,
{
use serde::Deserialize;
#[derive(Deserialize)]
#[serde(untagged)]
enum StringOrInt {
String(String),
Int(i64),
}
match StringOrInt::deserialize(d)? {
StringOrInt::String(s) => Ok(s),
StringOrInt::Int(n) => Ok(n.to_string()),
}
}
pub(crate) fn deserialize_id_as_i64<'de, D>(d: D) -> Result<i64, D::Error>
where
D: serde::Deserializer<'de>,
{
use serde::Deserialize;
#[derive(Deserialize)]
#[serde(untagged)]
enum StringOrInt {
String(String),
Int(i64),
}
match StringOrInt::deserialize(d)? {
StringOrInt::Int(n) => Ok(n),
StringOrInt::String(s) => s.parse::<i64>().map_err(serde::de::Error::custom),
}
}