use std::fmt;
use std::future::Future;
use chrono::{DateTime, Utc};
use mexc_rs::spot::v3::enums::KlineInterval;
use strum_macros::Display;
use thiserror::Error;
use super::clock::Clock;
use super::order::{Amount, Crypto, Order};
#[cfg(test)]
use mockall::automock;
pub mod mexc_base;
pub use mexc_rs::spot::v3::{
cancel_order::CancelOrderOutput, klines::Kline, query_order::QueryOrderOutput,
};
#[derive(Debug, Clone, Copy)]
pub struct Balance {
pub free: Amount,
pub locked: Amount,
}
#[derive(Debug, Error)]
pub enum MarketError {
#[error("Mexc API error: {0}")]
MexcApiError(#[from] anyhow::Error),
#[error("Safety error")]
SafetyError,
}
#[derive(Debug, Clone, Copy, Display, serde::Serialize, serde::Deserialize, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub enum MarketKind {
None,
Mexc,
TestMexc,
}
#[derive(Debug, Clone)]
pub struct KlinesParams {
pub symbol: String,
pub interval: KlineInterval,
pub start_time: Option<DateTime<Utc>>,
pub end_time: Option<DateTime<Utc>>,
pub limit: Option<u32>,
}
#[cfg_attr(test, automock)]
pub trait Market: Send + Sync + fmt::Debug + 'static {
fn clock(&self) -> Box<dyn Clock>;
fn klines(
&self,
params: KlinesParams,
) -> impl Future<Output = Result<Vec<Kline>, MarketError>> + Send;
fn get_balance(
&self,
crypto: Crypto,
) -> impl Future<Output = Result<Balance, MarketError>> + Send;
fn send_order(&self, order: &Order)
-> impl Future<Output = Result<String, MarketError>> + Send;
fn cancel_order(
&self,
order: &Order,
) -> impl Future<Output = Result<CancelOrderOutput, MarketError>> + Send;
fn update_order(
&self,
order: &Order,
) -> impl Future<Output = Result<QueryOrderOutput, MarketError>> + Send;
}