use crate::Identifier;
use barter_integration::subscription::SubscriptionId;
use serde::{Deserialize, Serialize};
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Deserialize, Serialize)]
#[serde(untagged, rename_all = "snake_case")]
pub enum KrakenMessage<T> {
Data(T),
Event(KrakenEvent),
}
impl<T> Identifier<Option<SubscriptionId>> for KrakenMessage<T>
where
T: Identifier<Option<SubscriptionId>>,
{
fn id(&self) -> Option<SubscriptionId> {
match self {
Self::Data(data) => data.id(),
Self::Event(_) => None,
}
}
}
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Deserialize, Serialize)]
#[serde(tag = "event", rename_all = "camelCase")]
pub enum KrakenEvent {
Heartbeat,
Error(KrakenError),
}
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Deserialize, Serialize)]
pub struct KrakenError {
#[serde(alias = "errorMessage")]
pub message: String,
}
#[cfg(test)]
mod tests {
use super::*;
mod de {
use super::*;
use barter_integration::error::SocketError;
#[test]
fn test_kraken_message_event() {
struct TestCase {
input: &'static str,
expected: Result<KrakenMessage<()>, SocketError>,
}
let tests = vec![
TestCase {
input: r#"{"event": "heartbeat"}"#,
expected: Ok(KrakenMessage::Event(KrakenEvent::Heartbeat)),
},
TestCase {
input: r#"{"errorMessage": "Malformed request", "event": "error"}"#,
expected: Ok(KrakenMessage::Event(KrakenEvent::Error(KrakenError {
message: "Malformed request".to_string(),
}))),
},
];
for (index, test) in tests.into_iter().enumerate() {
let actual = serde_json::from_str::<KrakenMessage<()>>(test.input);
match (actual, test.expected) {
(Ok(actual), Ok(expected)) => {
assert_eq!(actual, expected, "TC{} failed", index)
}
(Err(_), Err(_)) => {
}
(actual, expected) => {
panic!(
"TC{index} failed because actual != expected. \nActual: {actual:?}\nExpected: {expected:?}\n"
);
}
}
}
}
}
}