use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SubscriptionDefinition {
pub subject: String,
pub handler: String,
pub handler_type: HandlerType,
#[serde(default)]
pub config: HashMap<String, String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub stream: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum HandlerType {
DeleteCascade,
UpdateField,
Webhook,
Wasm,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_subscription_stream_defaults_to_none_in_legacy_json() {
let json = r#"{"subject":"x","handler":"h","handler_type":"wasm"}"#;
let sub: SubscriptionDefinition = serde_json::from_str(json).unwrap();
assert!(sub.stream.is_none());
}
#[test]
fn test_subscription_stream_roundtrip_when_set() {
let sub = SubscriptionDefinition {
subject: "cufflink.tick.5min".into(),
handler: "handle_tick_resync".into(),
handler_type: HandlerType::Wasm,
config: HashMap::new(),
stream: Some("CUFFLINK_TICKS".into()),
};
let json = serde_json::to_string(&sub).unwrap();
assert!(json.contains("\"stream\":\"CUFFLINK_TICKS\""));
let parsed: SubscriptionDefinition = serde_json::from_str(&json).unwrap();
assert_eq!(parsed.stream.as_deref(), Some("CUFFLINK_TICKS"));
}
#[test]
fn test_subscription_stream_skipped_when_none() {
let sub = SubscriptionDefinition {
subject: "x".into(),
handler: "h".into(),
handler_type: HandlerType::Wasm,
config: HashMap::new(),
stream: None,
};
let json = serde_json::to_string(&sub).unwrap();
assert!(!json.contains("stream"));
}
}