Why does this code not deserialize the messages correctly?
The first message received is expected to fail, because the data field = {}, but after that the data field matches the Trade structure which is part of the flattened enum Data.
What am I doing wrong?
Here is the output:
***> {"event":"bts:subscription_succeeded","channel":"live_trades_btcusd","data":{}}
===> Error("no variant of enum Data found in flattened data", line: 1, column: 79)
***> {"data":{"id":220315257,"timestamp":"1644180636","amount":0.03208,"amount_str":"0.03208000","price":41586.11,"price_str":"41586.11","type":0,"microtimestamp":"1644180636419000","buy_order_id":1455495830577152,"sell_order_id":1455495778422789},"channel":"live_trades_btcusd","event":"trade"}
===> Error("no variant of enum Data found in flattened data", line: 1, column: 290)
***> {"data":{"id":220315276,"timestamp":"1644180648","amount":0.02037389,"amount_str":"0.02037389","price":41586.11,"price_str":"41586.11","type":1,"microtimestamp":"1644180648235000","buy_order_id":1455495864238080,"sell_order_id":1455495878971395},"channel":"live_trades_btcusd","event":"trade"}
use serde::{Deserialize, Serialize};
use serde_json::json;
use tungstenite::{connect, Message};
use url::Url;
#[derive(Serialize, Deserialize, Debug)]
enum Data {
None,
Trade(Trade),
}
#[derive(Serialize, Deserialize, Debug)]
struct Msg {
channel: String,
event: String,
#[serde(flatten)]
data: Data,
}
#[derive(Serialize, Deserialize, Debug)]
struct Trade {
id: u32,
amount: f32,
amount_str: String,
buy_order_id: u64,
microtimestamp: String,
price: f32,
price_str: String,
sell_order_id: u64,
timestamp: String,
#[serde(rename = "type")]
_type: u8,
}
fn main() {
let (mut socket, _response) =
connect(Url::parse("wss://ws.bitstamp.net").unwrap()).expect("Can't connect");
socket
.write_message(
Message::Text(
json!({
"event": "bts:subscribe",
"data": {
"channel": "live_trades_btcusd"
}
})
.to_string(),
)
.into(),
)
.expect("Error sending message");
loop {
let msg = socket.read_message().expect("Error reading message");
println!("***> {}", msg);
let result: Result<Msg, serde_json::Error> = serde_json::from_str(msg.to_text().unwrap());
let _value = match result {
Ok(msg) => {
println!("---> {:?}", msg);
}
Err(err) => {
println!("===> {:?}", err);
continue;
}
};
}
}