cufflink-types 0.11.0

Shared type definitions for the Cufflink CRUD microservice platform
Documentation
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>,
    /// Explicit JetStream stream to host this subscription's consumer. When
    /// `None`, the platform uses the tenant stream (`DW_{tenant}`).
    #[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"));
    }
}