use serde::{Deserialize, Serialize};
use serde_json::Value;
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct ChannelConfig {
#[serde(default)]
pub rate_limit: Option<ChannelRateLimitConfig>,
#[serde(default)]
pub timeout_ms: Option<u64>,
#[serde(default)]
pub cache: Option<ChannelCacheConfig>,
#[serde(default)]
pub cors: Option<ChannelCorsConfig>,
#[serde(default)]
pub backpressure: Option<BackpressureConfig>,
#[serde(default)]
pub deduplication: Option<DeduplicationConfig>,
#[serde(default)]
pub validation_logic: Option<Value>,
#[serde(default)]
pub tracing: Option<ChannelTracingConfig>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct ChannelTracingConfig {
#[serde(default)]
pub mode: Option<crate::config::TraceStorageMode>,
#[serde(default)]
pub sample_rate: Option<f64>,
#[serde(default)]
pub errors_only: Option<bool>,
#[serde(default)]
pub task_details: Option<bool>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ChannelRateLimitConfig {
pub requests_per_second: u32,
#[serde(default)]
pub burst: Option<u32>,
#[serde(default)]
pub key_logic: Option<Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ChannelCacheConfig {
pub enabled: bool,
#[serde(default)]
pub ttl_secs: Option<u64>,
#[serde(default)]
pub cache_key_fields: Option<Vec<String>>,
#[serde(default)]
pub connector: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ChannelCorsConfig {
#[serde(default)]
pub allowed_origins: Option<Vec<String>>,
#[serde(default)]
pub allowed_methods: Option<Vec<String>>,
#[serde(default)]
pub allowed_headers: Option<Vec<String>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BackpressureConfig {
pub max_concurrent: usize,
#[serde(default)]
pub queue_depth: Option<usize>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DeduplicationConfig {
pub header: String,
#[serde(default)]
pub window_secs: Option<u64>,
#[serde(default)]
pub connector: Option<String>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_channel_config_default() {
let config = ChannelConfig::default();
assert!(config.rate_limit.is_none());
assert!(config.timeout_ms.is_none());
assert!(config.cache.is_none());
assert!(config.backpressure.is_none());
assert!(config.deduplication.is_none());
assert!(config.validation_logic.is_none());
}
#[test]
fn test_channel_config_deserialization() {
let json = r#"{
"rate_limit": { "requests_per_second": 100, "burst": 20, "key_logic": { "var": "client_ip" } },
"timeout_ms": 5000,
"backpressure": { "max_concurrent": 200 },
"deduplication": { "header": "Idempotency-Key", "window_secs": 300 }
}"#;
let config: ChannelConfig = serde_json::from_str(json).expect("test");
let rl = config.rate_limit.expect("test");
assert_eq!(rl.requests_per_second, 100);
assert_eq!(rl.burst, Some(20));
assert!(rl.key_logic.is_some());
assert_eq!(config.timeout_ms, Some(5000));
let bp = config.backpressure.expect("test");
assert_eq!(bp.max_concurrent, 200);
let dedup = config.deduplication.expect("test");
assert_eq!(dedup.header, "Idempotency-Key");
assert_eq!(dedup.window_secs, Some(300));
}
#[test]
fn test_channel_config_empty_json() {
let config: ChannelConfig = serde_json::from_str("{}").expect("test");
assert!(config.rate_limit.is_none());
assert!(config.timeout_ms.is_none());
}
}