use serde::{Deserialize, Deserializer};
use crate::utils::AssetId;
use crate::utils::json::Json;
use crate::utils::sign::goldilocks::Fp;
use crate::utils::sign::tx::{Tx, TxType, element, number};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub enum TradingMode {
#[default]
Classic,
Unified,
}
impl TradingMode {
#[must_use]
pub const fn code(self) -> u8 {
match self {
TradingMode::Classic => 0,
TradingMode::Unified => 1,
}
}
#[must_use]
pub const fn from_code(code: u64) -> Option<TradingMode> {
match code {
0 => Some(TradingMode::Classic),
1 => Some(TradingMode::Unified),
_ => None,
}
}
}
pub(crate) fn known_mode<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Option<TradingMode>, D::Error> {
let code = Option::<u64>::deserialize(deserializer)?;
Ok(code.and_then(TradingMode::from_code))
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct UpdateAccountConfig {
pub mode: TradingMode,
}
impl UpdateAccountConfig {
#[must_use]
pub const fn new(mode: TradingMode) -> UpdateAccountConfig {
UpdateAccountConfig { mode }
}
}
impl Tx for UpdateAccountConfig {
fn tx_type(&self) -> TxType {
TxType::UpdateAccountConfig
}
fn hash_fields(&self) -> Vec<Fp> {
vec![element(self.mode.code())]
}
fn info_fields(&self) -> Vec<(&'static str, Json)> {
vec![("AccountTradingMode", number(self.mode.code()))]
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct UpdateAccountAssetConfig {
pub asset: AssetId,
pub margin: bool,
}
impl UpdateAccountAssetConfig {
#[must_use]
pub const fn enable(asset: AssetId) -> UpdateAccountAssetConfig {
UpdateAccountAssetConfig { asset, margin: true }
}
#[must_use]
pub const fn disable(asset: AssetId) -> UpdateAccountAssetConfig {
UpdateAccountAssetConfig { asset, margin: false }
}
#[must_use]
pub const fn margin_code(&self) -> u8 {
match self.margin {
true => 1,
false => 0,
}
}
}
impl Tx for UpdateAccountAssetConfig {
fn tx_type(&self) -> TxType {
TxType::UpdateAccountAssetConfig
}
fn hash_fields(&self) -> Vec<Fp> {
vec![element(self.asset.get()), element(self.margin_code())]
}
fn info_fields(&self) -> Vec<(&'static str, Json)> {
vec![("AssetIndex", number(self.asset.get())), ("AssetMarginMode", number(self.margin_code()))]
}
}
#[cfg(test)]
#[path = "tests/mode.rs"]
mod tests;