use rustrade_integration::{Validator, error::SocketError};
use serde::{Deserialize, Serialize};
#[derive(Clone, Eq, PartialEq, Debug, Deserialize, Serialize)]
#[serde(tag = "channel", rename_all = "camelCase")]
pub enum HyperliquidSubResponse {
SubscriptionResponse { data: HyperliquidSubResponseData },
Pong,
Error { data: String },
}
#[derive(Clone, Eq, PartialEq, Debug, Deserialize, Serialize)]
pub struct HyperliquidSubResponseData {
pub method: String,
pub subscription: serde_json::Value,
}
impl Validator for HyperliquidSubResponse {
type Error = SocketError;
fn validate(self) -> Result<Self, SocketError>
where
Self: Sized,
{
match &self {
HyperliquidSubResponse::SubscriptionResponse { .. } => Ok(self),
HyperliquidSubResponse::Pong => Err(SocketError::Subscribe(
"received pong out of sequence during subscription validation".to_owned(),
)),
HyperliquidSubResponse::Error { data } => Err(SocketError::Subscribe(format!(
"received failure subscription response: {data}",
))),
}
}
}
#[cfg(test)]
#[allow(clippy::unwrap_used)] mod tests {
use super::*;
mod de {
use super::*;
#[test]
fn test_hyperliquid_sub_response_success() {
let input = r#"
{
"channel": "subscriptionResponse",
"data": {
"method": "subscribe",
"subscription": {"type": "trades", "coin": "BTC"}
}
}
"#;
let response: HyperliquidSubResponse = serde_json::from_str(input).unwrap();
assert!(matches!(
response,
HyperliquidSubResponse::SubscriptionResponse { .. }
));
assert!(response.validate().is_ok());
}
#[test]
fn test_hyperliquid_sub_response_pong() {
let input = r#"{"channel": "pong"}"#;
let response: HyperliquidSubResponse = serde_json::from_str(input).unwrap();
assert!(matches!(response, HyperliquidSubResponse::Pong));
assert!(response.validate().is_err());
}
#[test]
fn test_hyperliquid_sub_response_error() {
let input = r#"{"channel": "error", "data": "invalid subscription"}"#;
let response: HyperliquidSubResponse = serde_json::from_str(input).unwrap();
assert!(matches!(response, HyperliquidSubResponse::Error { .. }));
assert!(response.validate().is_err());
}
}
}