use serde::{Deserialize, Serialize};
use serde_repr::{Deserialize_repr, Serialize_repr};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GenericResponse {
pub result: bool,
pub errormsg: Option<String>,
pub errorcode: i32,
pub detail: Option<String>,
}
#[derive(
Debug, Clone, Copy, PartialEq, Eq, Serialize_repr, Deserialize_repr,
)]
#[repr(u8)]
pub enum Side {
Buy = 0,
Sell = 1,
Short = 2,
Unknown = 3,
}
#[derive(
Debug, Clone, Copy, PartialEq, Eq, Serialize_repr, Deserialize_repr,
)]
#[repr(u8)]
pub enum OrderType {
Unknown = 0,
Market = 1,
Limit = 2,
StopMarket = 3,
StopLimit = 4,
TrailingStopMarket = 5,
TrailingStopLimit = 6,
BlockTrade = 7,
}
#[derive(
Debug, Clone, Copy, PartialEq, Eq, Serialize_repr, Deserialize_repr,
)]
#[repr(u8)]
pub enum TimeInForce {
Unknown = 0,
GTC = 1,
OPG = 2,
IOC = 3,
FOK = 4,
GTX = 5,
GTD = 6,
}
#[derive(
Debug, Clone, Copy, PartialEq, Eq, Serialize_repr, Deserialize_repr,
)]
#[repr(u8)]
pub enum ActionType {
New = 0,
Update = 1,
Delete = 2,
}
#[derive(
Debug, Clone, Copy, PartialEq, Eq, Serialize_repr, Deserialize_repr,
)]
#[repr(u8)]
pub enum OrderState {
Working = 0,
Rejected = 1,
FullyExecuted = 2,
Canceled = 3,
Expired = 4,
PartiallyExecuted = 5,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_side_serialization() {
assert_eq!(serde_json::to_string(&Side::Buy).unwrap(), "0");
assert_eq!(serde_json::to_string(&Side::Sell).unwrap(), "1");
assert_eq!(serde_json::to_string(&Side::Short).unwrap(), "2");
assert_eq!(serde_json::to_string(&Side::Unknown).unwrap(), "3");
}
#[test]
fn test_side_deserialization() {
assert_eq!(serde_json::from_str::<Side>("0").unwrap(), Side::Buy);
assert_eq!(serde_json::from_str::<Side>("1").unwrap(), Side::Sell);
assert_eq!(serde_json::from_str::<Side>("2").unwrap(), Side::Short);
assert_eq!(serde_json::from_str::<Side>("3").unwrap(), Side::Unknown);
}
#[test]
fn test_order_type_values() {
assert_eq!(OrderType::Unknown as u8, 0);
assert_eq!(OrderType::Market as u8, 1);
assert_eq!(OrderType::Limit as u8, 2);
assert_eq!(OrderType::StopMarket as u8, 3);
assert_eq!(OrderType::StopLimit as u8, 4);
assert_eq!(OrderType::TrailingStopMarket as u8, 5);
assert_eq!(OrderType::TrailingStopLimit as u8, 6);
assert_eq!(OrderType::BlockTrade as u8, 7);
}
#[test]
fn test_order_type_serialization() {
assert_eq!(serde_json::to_string(&OrderType::Market).unwrap(), "1");
assert_eq!(serde_json::to_string(&OrderType::Limit).unwrap(), "2");
assert_eq!(
serde_json::from_str::<OrderType>("1").unwrap(),
OrderType::Market
);
assert_eq!(
serde_json::from_str::<OrderType>("2").unwrap(),
OrderType::Limit
);
}
#[test]
fn test_time_in_force_values() {
assert_eq!(TimeInForce::Unknown as u8, 0);
assert_eq!(TimeInForce::GTC as u8, 1);
assert_eq!(TimeInForce::OPG as u8, 2);
assert_eq!(TimeInForce::IOC as u8, 3);
assert_eq!(TimeInForce::FOK as u8, 4);
assert_eq!(TimeInForce::GTX as u8, 5);
assert_eq!(TimeInForce::GTD as u8, 6);
}
#[test]
fn test_time_in_force_serialization() {
assert_eq!(serde_json::to_string(&TimeInForce::GTC).unwrap(), "1");
assert_eq!(serde_json::to_string(&TimeInForce::IOC).unwrap(), "3");
assert_eq!(serde_json::to_string(&TimeInForce::FOK).unwrap(), "4");
assert_eq!(
serde_json::from_str::<TimeInForce>("1").unwrap(),
TimeInForce::GTC
);
}
#[test]
fn test_action_type_values() {
assert_eq!(ActionType::New as u8, 0);
assert_eq!(ActionType::Update as u8, 1);
assert_eq!(ActionType::Delete as u8, 2);
assert_eq!(serde_json::to_string(&ActionType::New).unwrap(), "0");
assert_eq!(
serde_json::from_str::<ActionType>("2").unwrap(),
ActionType::Delete
);
}
#[test]
fn test_order_state_values() {
assert_eq!(OrderState::Working as u8, 0);
assert_eq!(OrderState::Rejected as u8, 1);
assert_eq!(OrderState::FullyExecuted as u8, 2);
assert_eq!(OrderState::Canceled as u8, 3);
assert_eq!(OrderState::Expired as u8, 4);
assert_eq!(OrderState::PartiallyExecuted as u8, 5);
}
#[test]
fn test_order_state_serialization() {
assert_eq!(serde_json::to_string(&OrderState::Working).unwrap(), "0");
assert_eq!(
serde_json::to_string(&OrderState::FullyExecuted).unwrap(),
"2"
);
assert_eq!(
serde_json::from_str::<OrderState>("3").unwrap(),
OrderState::Canceled
);
}
#[test]
fn test_generic_response_success() {
let json = r#"{"result":true,"errormsg":"","errorcode":0,"detail":null}"#;
let response: GenericResponse = serde_json::from_str(json).unwrap();
assert!(response.result);
assert_eq!(response.errorcode, 0);
}
#[test]
fn test_generic_response_success_empty_errormsg() {
let json = r#"{"result":true,"errormsg":null,"errorcode":0}"#;
let response: GenericResponse = serde_json::from_str(json).unwrap();
assert!(response.result);
assert!(response.errormsg.is_none());
assert!(response.detail.is_none());
}
#[test]
fn test_generic_response_error() {
let json = r#"{"result":false,"errormsg":"Invalid InstrumentId","errorcode":100,"detail":"ID not found"}"#;
let response: GenericResponse = serde_json::from_str(json).unwrap();
assert!(!response.result);
assert_eq!(response.errormsg, Some("Invalid InstrumentId".to_string()));
assert_eq!(response.errorcode, 100);
assert_eq!(response.detail, Some("ID not found".to_string()));
}
}