From 5ab45b3b370c38d89438ddc65f93b5ac3bd48aaa Mon Sep 17 00:00:00 2001 From: Jan Rock Date: Sun, 27 Oct 2024 11:10:50 +0000 Subject: [PATCH] refactoring --- src/models/model.rs | 103 +++++++++++++++++++++++++++++++++++++++++++- src/server.rs | 99 ++---------------------------------------- 2 files changed, 105 insertions(+), 97 deletions(-) diff --git a/src/models/model.rs b/src/models/model.rs index 0a44b6a..a0be0e3 100644 --- a/src/models/model.rs +++ b/src/models/model.rs @@ -1,5 +1,12 @@ pub mod models { - use serde::Deserialize; + use std::fmt; + use ordered_float::OrderedFloat; + use serde::{ Serialize, Serializer, ser::SerializeStruct, Deserialize, Deserializer }; + use uuid::Uuid; + + use colored::*; + extern crate env_logger; + extern crate log; pub mod orderbook { tonic::include_proto!("orderbook"); @@ -16,4 +23,96 @@ pub mod models { pub persist: String, pub offline: Vec, } -} \ No newline at end of file + + // For Orderbook + #[derive(Debug, Clone, PartialEq, Eq)] + pub struct Order { + pub id: Uuid, + pub price: OrderedFloat, + pub volume: OrderedFloat, + pub side: String, + pub timestamp: String, + pub order_type: String, + } + + // Custom deserialization for Order + impl<'de> Deserialize<'de> for Order { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + #[derive(Deserialize)] + struct OrderData { + price: f64, + volume: f64, + side: String, + timestamp: String, + order_type: String, + } + + let helper = OrderData::deserialize(deserializer)?; + //let id = Uuid::parse_str(&helper.id).map_err(de::Error::custom)?; + + Ok(Order { + id: Uuid::new_v4(), + price: OrderedFloat(helper.price), + volume: OrderedFloat(helper.volume), + side: helper.side, + timestamp: helper.timestamp, + order_type: helper.order_type, + }) + } + } + + // Custom serialization for Order (to avoid serialization of OrderedFloat for csv crate) + // TODO: find a better way to handle serialization of OrderedFloat + impl Serialize for Order { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut state: ::SerializeStruct = + serializer.serialize_struct("Order", 5)?; + state.serialize_field("price", &self.price.into_inner())?; + state.serialize_field("volume", &self.volume.into_inner())?; + state.serialize_field("side", &self.side)?; + state.serialize_field("timestamp", &self.timestamp)?; + state.serialize_field("order_type", &self.order_type)?; + //state.serialize_field("id", &self.id.to_string())?; + state.end() + } + } + + // Implement the Display trait for the Order struct (more readable output with colors) + impl fmt::Display for Order { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let output: String = format!( + "Price: {:.5}, Volume: {:.3}, Side: {}, ID: {}, Timestamp: {}", + self.price, + self.volume, + self.side, + self.id, + self.timestamp + ); + if self.side == "ask" { + write!(f, "{}", output.red()) + } else { + write!(f, "{}", output.green()) + } + } + } + + //For Tradebook + #[derive(Debug, Clone, PartialEq, Eq)] + pub struct Trade { + pub id: Uuid, + pub trader: String, + pub pair: String, + pub price: OrderedFloat, + pub volume: OrderedFloat, + pub side: String, + pub timestamp: String, + pub order_type: String, + pub status: String, + } +} diff --git a/src/server.rs b/src/server.rs index 178c853..6efd45b 100644 --- a/src/server.rs +++ b/src/server.rs @@ -1,7 +1,6 @@ use std::collections::HashMap; use std::env; use std::fs::File; -use std::fmt; use std::sync::Arc; use std::error::Error; use models::model::models::Config; @@ -11,17 +10,11 @@ use tonic::{ transport::Server, Request, Response, Status }; use futures::future::join_all; use csv::{ ReaderBuilder, Writer }; use chrono::Utc; -use serde::{ Serialize, Serializer, ser::SerializeStruct, Deserialize, Deserializer }; use serde_json::Value; use ordered_float::OrderedFloat; use uuid::Uuid; use crate::utils::config::load_config; -use colored::*; -extern crate env_logger; -extern crate log; -use log::info; - use orderbook::order_book_server::{ OrderBook, OrderBookServer }; use orderbook::{ OrderBookRequest, @@ -38,6 +31,10 @@ pub mod orderbook { tonic::include_proto!("orderbook"); } +use log::info; + +use crate::models::model::models::{ Order, Trade }; + #[derive(Debug)] pub struct OrderBookService { order_books: Arc>>>, @@ -45,94 +42,6 @@ pub struct OrderBookService { trade_books: Arc>>>, } -// For Orderbook -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct Order { - id: Uuid, - price: OrderedFloat, - volume: OrderedFloat, - side: String, - timestamp: String, - order_type: String, -} - -//For Tradebook -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct Trade { - id: Uuid, - trader: String, - pair: String, - price: OrderedFloat, - volume: OrderedFloat, - side: String, - timestamp: String, - order_type: String, - status: String, -} - -// Custom deserialization for Order -impl<'de> Deserialize<'de> for Order { - fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { - #[derive(Deserialize)] - struct OrderData { - price: f64, - volume: f64, - side: String, - timestamp: String, - order_type: String, - } - - let helper = OrderData::deserialize(deserializer)?; - //let id = Uuid::parse_str(&helper.id).map_err(de::Error::custom)?; - - Ok(Order { - id: Uuid::new_v4(), - price: OrderedFloat(helper.price), - volume: OrderedFloat(helper.volume), - side: helper.side, - timestamp: helper.timestamp, - order_type: helper.order_type, - }) - } -} - -// Custom serialization for Order (to avoid serialization of OrderedFloat for csv crate) -// TODO: find a better way to handle serialization of OrderedFloat -impl Serialize for Order { - fn serialize(&self, serializer: S) -> Result where S: Serializer { - let mut state: ::SerializeStruct = serializer.serialize_struct( - "Order", - 5 - )?; - state.serialize_field("price", &self.price.into_inner())?; - state.serialize_field("volume", &self.volume.into_inner())?; - state.serialize_field("side", &self.side)?; - state.serialize_field("timestamp", &self.timestamp)?; - state.serialize_field("order_type", &self.order_type)?; - //state.serialize_field("id", &self.id.to_string())?; - state.end() - } -} - -// Implement the Display trait for the Order struct (more readable output with colors) -impl fmt::Display for Order { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let output: String = format!( - "Price: {:.5}, Volume: {:.3}, Side: {}, ID: {}, Timestamp: {}", - self.price, - self.volume, - self.side, - self.id, - self.timestamp - ); - if self.side == "ask" { - write!(f, "{}", output.red()) - } else { - write!(f, "{}", output.green()) - } - } -} - // Implement the OrderBook trait for OrderBookService to handle gRPC requests (core) #[tonic::async_trait] impl OrderBook for Arc {