use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct NatsConfig {
pub url: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub token: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub credentials_path: Option<String>,
pub stream_name: String,
pub subject_prefix: String,
pub storage: StorageType,
pub max_events: i64,
pub max_age_secs: u64,
pub max_bytes: i64,
pub connect_timeout_secs: u64,
pub request_timeout_secs: u64,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum StorageType {
File,
Memory,
}
impl Default for NatsConfig {
fn default() -> Self {
Self {
url: "nats://127.0.0.1:4222".to_string(),
token: None,
credentials_path: None,
stream_name: "A3S_EVENTS".to_string(),
subject_prefix: "events".to_string(),
storage: StorageType::File,
max_events: 100_000,
max_age_secs: 604_800, max_bytes: 0, connect_timeout_secs: 5,
request_timeout_secs: 10,
}
}
}
impl NatsConfig {
pub fn stream_subjects(&self) -> Vec<String> {
vec![format!("{}.>", self.subject_prefix)]
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_config() {
let config = NatsConfig::default();
assert_eq!(config.url, "nats://127.0.0.1:4222");
assert_eq!(config.stream_name, "A3S_EVENTS");
assert_eq!(config.subject_prefix, "events");
assert_eq!(config.storage, StorageType::File);
assert_eq!(config.max_events, 100_000);
assert_eq!(config.max_age_secs, 604_800);
assert_eq!(config.connect_timeout_secs, 5);
}
#[test]
fn test_stream_subjects() {
let config = NatsConfig::default();
assert_eq!(config.stream_subjects(), vec!["events.>"]);
}
#[test]
fn test_config_serialization() {
let config = NatsConfig::default();
let json = serde_json::to_string(&config).unwrap();
assert!(json.contains("\"streamName\":\"A3S_EVENTS\""));
assert!(!json.contains("token"));
let parsed: NatsConfig = serde_json::from_str(&json).unwrap();
assert_eq!(parsed.stream_name, "A3S_EVENTS");
assert!(parsed.token.is_none());
}
#[test]
fn test_storage_type_serialization() {
let file_json = serde_json::to_string(&StorageType::File).unwrap();
assert_eq!(file_json, "\"file\"");
let mem_json = serde_json::to_string(&StorageType::Memory).unwrap();
assert_eq!(mem_json, "\"memory\"");
let parsed: StorageType = serde_json::from_str("\"memory\"").unwrap();
assert_eq!(parsed, StorageType::Memory);
}
}