Last active
September 30, 2023 02:46
-
-
Save jaredmcqueen/c8a56c6a919bf15a214fd865744fdc70 to your computer and use it in GitHub Desktop.
serde serializing and deserializing using enums and structs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // cargo.toml: | |
| // serde = { version = "1", features = ["derive"] } | |
| // serde_json = "1" | |
| use serde::{Deserialize, Serialize}; | |
| #[derive(Serialize, Debug)] | |
| #[serde(tag = "action")] | |
| pub enum ClientMessage { | |
| #[serde(rename = "auth")] | |
| Auth(AuthMessage), | |
| #[serde(rename = "subscribe")] | |
| Subscribe(SubscriptionMessage), | |
| #[serde(rename = "unsubscribe")] | |
| Unsubscribe(SubscriptionMessage), | |
| } | |
| #[derive(Debug, Serialize, Clone)] | |
| pub struct AuthMessage { | |
| pub key: String, | |
| pub secret: String, | |
| } | |
| #[derive(Debug, Serialize, Clone)] | |
| pub struct SubscriptionMessage { | |
| #[serde(skip_serializing_if = "Option::is_none")] | |
| pub trades: Option<Vec<String>>, | |
| #[serde(skip_serializing_if = "Option::is_none")] | |
| pub quotes: Option<Vec<String>>, | |
| #[serde(skip_serializing_if = "Option::is_none")] | |
| pub bars: Option<Vec<String>>, | |
| } | |
| #[derive(Deserialize, Debug)] | |
| #[serde(tag = "T")] | |
| pub enum WebSocketEvent { | |
| #[serde(rename = "success")] | |
| Success(SuccessMessage), | |
| #[serde(rename = "error")] | |
| Error(ErrorEvent), | |
| #[serde(rename = "subscription")] | |
| Subscription(SubscriptionEvent), | |
| #[serde(rename = "t")] | |
| Trade(TradeEvent), | |
| #[serde(rename = "q")] | |
| Quote(QuoteEvent), | |
| #[serde(rename = "b")] | |
| Bar(BarEvent), | |
| #[serde(rename = "d")] | |
| DailyBar(BarEvent), | |
| #[serde(rename = "u")] | |
| UpdatedBar(BarEvent), | |
| } | |
| #[derive(Debug, Deserialize, Clone)] | |
| pub struct SubscriptionEvent { | |
| #[serde(rename = "trades")] | |
| pub trades: Vec<String>, | |
| #[serde(rename = "quotes")] | |
| pub quotes: Vec<String>, | |
| #[serde(rename = "bars")] | |
| pub bars: Vec<String>, | |
| #[serde(rename = "updatedBars")] | |
| pub updated_bars: Vec<String>, | |
| #[serde(rename = "dailyBars")] | |
| pub daily_bars: Vec<String>, | |
| #[serde(rename = "statuses")] | |
| pub statuses: Vec<String>, | |
| #[serde(rename = "lulds")] | |
| pub lulds: Vec<String>, | |
| #[serde(rename = "corrections")] | |
| pub corrections: Vec<String>, | |
| #[serde(rename = "cancelErrors")] | |
| pub cancel_errors: Vec<String>, | |
| } | |
| #[derive(Debug, Deserialize, Clone)] | |
| pub struct SuccessMessage { | |
| #[serde(rename = "msg")] | |
| pub message: String, | |
| } | |
| #[derive(Debug, Deserialize, Clone)] | |
| pub struct ErrorEvent { | |
| #[serde(rename = "msg")] | |
| pub message: String, | |
| #[serde(rename = "code")] | |
| pub code: u16, | |
| } | |
| #[derive(Debug, Deserialize, Clone)] | |
| pub struct TradeEvent { | |
| #[serde(rename = "S")] | |
| pub symbol: String, | |
| #[serde(rename = "i")] | |
| pub trade_id: u64, | |
| #[serde(rename = "x")] | |
| pub exchange_code: String, | |
| #[serde(rename = "p")] | |
| pub trade_price: f64, | |
| #[serde(rename = "s")] | |
| pub trade_size: u64, | |
| #[serde(rename = "t")] | |
| pub timestamp: String, | |
| #[serde(rename = "c")] | |
| pub trade_condition: Vec<String>, | |
| #[serde(rename = "z")] | |
| pub tape: String, | |
| } | |
| #[derive(Debug, Deserialize, Clone)] | |
| pub struct QuoteEvent { | |
| #[serde(rename = "S")] | |
| pub symbol: String, | |
| #[serde(rename = "ax")] | |
| pub ask_exchange_code: String, | |
| #[serde(rename = "ap")] | |
| pub ask_price: f64, | |
| #[serde(rename = "as")] | |
| pub ask_size: u64, | |
| #[serde(rename = "bx")] | |
| pub bid_exchange_code: String, | |
| #[serde(rename = "bp")] | |
| pub bid_price: f64, | |
| #[serde(rename = "bs")] | |
| pub bid_size: u64, | |
| #[serde(rename = "c")] | |
| pub quote_condition: Vec<String>, | |
| #[serde(rename = "t")] | |
| pub timestamp: String, | |
| #[serde(rename = "z")] | |
| pub tape: String, | |
| } | |
| #[derive(Debug, Deserialize, Clone)] | |
| pub struct BarEvent { | |
| #[serde(rename = "S")] | |
| pub symbol: String, | |
| #[serde(rename = "o")] | |
| pub open: f64, | |
| #[serde(rename = "h")] | |
| pub high: f64, | |
| #[serde(rename = "l")] | |
| pub low: f64, | |
| #[serde(rename = "c")] | |
| pub close: f64, | |
| #[serde(rename = "v")] | |
| pub volume: u64, | |
| #[serde(rename = "t")] | |
| pub timestamp: String, | |
| } | |
| fn main() { | |
| let connected = r#"{"T":"success","msg":"connected"}"#; | |
| let error = r#"{"T":"error","code":400,"msg":"connected"}"#; | |
| let trade = r#"{"T":"t","i":96921,"S":"AAPL","x":"D","p":126.55,"s":1,"t":"2021-02-22T15:51:44.208Z","c":["@","I"],"z":"C"}"#; | |
| let quote = r#"{"T":"q","S":"AMD","bx":"U","bp":87.66,"bs":1,"ax":"Q","ap":87.68,"as":4,"t":"2021-02-22T15:51:45.335689322Z","c":["R"],"z":"C"}"#; | |
| let bar = r#"{"T":"b","S":"SPY","o":388.985,"h":389.13,"l":388.975,"c":389.12,"v":49378,"t":"2021-02-22T19:15:00Z"}"#; | |
| let daily_bar = r#"{"T":"d","S":"SPY","o":388.985,"h":389.13,"l":388.975,"c":389.12,"v":49378,"t":"2021-02-22T19:15:00Z"}"#; | |
| let updated_bar = r#"{"T":"u","S":"SPY","o":388.985,"h":389.13,"l":388.975,"c":389.12,"v":49378,"t":"2021-02-22T19:15:00Z"}"#; | |
| let subscription = r#"{"T":"subscription","trades":["AAPL"],"quotes":["AMD","CLDR"],"bars":["*"],"updatedBars":[],"dailyBars":["VOO"],"statuses":["*"],"lulds":[],"corrections":["AAPL"],"cancelErrors":["AAPL"]}"#; | |
| let events = vec![ | |
| connected, | |
| error, | |
| trade, | |
| quote, | |
| bar, | |
| daily_bar, | |
| updated_bar, | |
| subscription, | |
| ]; | |
| for event_type in events { | |
| let event: WebSocketEvent = serde_json::from_str(event_type).unwrap(); | |
| dbg!(event); | |
| } | |
| let auth_message = ClientMessage::Auth(AuthMessage { | |
| key: "my-key".into(), | |
| secret: "my-secret".into(), | |
| }); | |
| let subscribe = ClientMessage::Subscribe(SubscriptionMessage { | |
| trades: Some(vec!["AAPL".into()]), | |
| quotes: Some(vec!["MSFT".into(), "TSLA".into()]), | |
| bars: None, | |
| }); | |
| let unsubscribe = ClientMessage::Unsubscribe(SubscriptionMessage { | |
| trades: Some(vec!["AAPL".into()]), | |
| quotes: Some(vec!["MSFT".into(), "TSLA".into()]), | |
| bars: None, | |
| }); | |
| let client_messages = vec![auth_message, subscribe, unsubscribe]; | |
| for message in client_messages { | |
| let json = serde_json::to_string(&message).expect("error bro"); | |
| dbg!(json); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment