mexc-rs 0.2.0

Rust client for the mexc.com exchange
Documentation
use async_trait::async_trait;
use bigdecimal::BigDecimal;
use crate::futures::{MexcFuturesApiClientWithAuthentication};
use crate::futures::auth::SignRequestParamsKind;
use crate::futures::response::ApiResponse;
use crate::futures::result::ApiResult;
use crate::futures::v1::models::{OpenType, OrderSide, OrderType, PositionMode};

#[derive(Debug)]
pub struct OrderParams<'a> {
    pub symbol: &'a str,
    pub price: BigDecimal,
    pub volume: BigDecimal,
    pub leverage: Option<u32>,
    pub side: OrderSide,
    pub order_type: OrderType,
    pub open_type: OpenType,
    pub position_id: Option<i64>,
    pub external_order_id: Option<&'a str>,
    pub stop_loss_price: Option<BigDecimal>,
    pub take_profit_price: Option<BigDecimal>,
    pub position_mode: Option<PositionMode>,
    pub reduce_only: Option<bool>,
}

#[derive(Debug)]
pub struct OrderOutput {
    pub order_id: i64,
}

#[async_trait]
pub trait Order {
    async fn order<'a>(&self, params: OrderParams<'a>) -> ApiResult<OrderOutput>;
}

#[derive(Debug, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct OrderPayload<'a> {
    pub symbol: &'a str,
    pub price: BigDecimal,
    #[serde(rename = "vol")]
    pub volume: BigDecimal,
    pub leverage: Option<u32>,
    pub side: OrderSide,
    pub order_type: OrderType,
    pub open_type: OpenType,
    pub position_id: Option<i64>,
    #[serde(rename = "externalOid")]
    pub external_order_id: Option<&'a str>,
    pub stop_loss_price: Option<BigDecimal>,
    pub take_profit_price: Option<BigDecimal>,
    pub position_mode: Option<PositionMode>,
    pub reduce_only: Option<bool>,
}

impl<'a> From<&OrderParams<'a>> for OrderPayload<'a> {
    fn from(params: &OrderParams<'a>) -> Self {
        OrderPayload {
            symbol: params.symbol,
            price: params.price.clone(),
            volume: params.volume.clone(),
            leverage: params.leverage,
            side: params.side.clone(),
            order_type: params.order_type.clone(),
            open_type: params.open_type.clone(),
            position_id: params.position_id,
            external_order_id: params.external_order_id,
            stop_loss_price: params.stop_loss_price.clone(),
            take_profit_price: params.take_profit_price.clone(),
            position_mode: params.position_mode.clone(),
            reduce_only: params.reduce_only,
        }
    }
}

#[async_trait]
impl Order for MexcFuturesApiClientWithAuthentication {
    async fn order<'a>(&self, params: OrderParams<'a>) -> ApiResult<OrderOutput> {
        let url = format!("{}/api/v1/private/order/submit", self.endpoint.as_ref());
        let payload = OrderPayload::from(&params);
        let auth_header_map = self.get_auth_header_map(&payload, SignRequestParamsKind::Body)?;
        let response = self.reqwest_client.post(&url).headers(auth_header_map).json(&payload).send().await?;
        let api_response = response.json::<ApiResponse<i64>>().await?;
        let order_id = api_response.into_api_result()?;

        Ok(OrderOutput { order_id })
    }
}