use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SportsUpdateMessage {
pub event_type: String,
#[serde(default)]
pub timestamp: Option<String>,
#[serde(flatten)]
pub data: serde_json::Value,
}
#[derive(Debug, Clone, Serialize)]
#[serde(untagged)]
#[non_exhaustive]
pub enum SportsMessage {
Update(SportsUpdateMessage),
}
impl SportsMessage {
pub fn from_json(json: &str) -> Result<Self, serde_json::Error> {
Ok(SportsMessage::Update(serde_json::from_str(json)?))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parses_sports_update_and_retains_unknown_fields() {
let json = r#"{
"event_type": "sports_update",
"timestamp": "1700000000000",
"game_id": "g-1",
"period": 2,
"score": {"home": 21, "away": 14}
}"#;
let SportsMessage::Update(msg) = SportsMessage::from_json(json).unwrap();
assert_eq!(msg.event_type, "sports_update");
assert_eq!(msg.timestamp.as_deref(), Some("1700000000000"));
assert_eq!(msg.data["game_id"], "g-1");
assert_eq!(msg.data["score"]["home"], 21);
}
#[test]
fn tolerates_missing_timestamp() {
let json = r#"{"event_type": "sports_update", "game_id": "g-2"}"#;
let SportsMessage::Update(msg) = SportsMessage::from_json(json).unwrap();
assert_eq!(msg.timestamp, None);
assert_eq!(msg.data["game_id"], "g-2");
}
}