#[cfg(feature = "edge-proxy")]
pub mod cache;
#[cfg(feature = "edge-proxy")]
pub mod client;
#[cfg(feature = "edge-proxy")]
pub mod fingerprint;
#[cfg(feature = "edge-proxy")]
pub mod registry;
#[cfg(feature = "edge-proxy")]
pub use cache::{CacheEntry, CacheKey, EdgeCache, EdgeCacheStats};
#[cfg(feature = "edge-proxy")]
pub use registry::{EdgeNode, EdgeRegistry, InvalidationEvent};
use serde::{Deserialize, Serialize};
use std::time::Duration;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct EdgeConfig {
#[serde(default)]
pub enabled: bool,
#[serde(default = "default_role")]
pub role: EdgeRole,
#[serde(default)]
pub home_url: String,
#[serde(default)]
pub auth_token: String,
#[serde(default)]
pub allow_insecure_home_url: bool,
#[serde(default = "default_cache_ttl_secs")]
pub default_ttl_secs: u64,
#[serde(default = "default_max_entries")]
pub max_entries: usize,
#[serde(default = "default_max_edges")]
pub max_edges: usize,
#[serde(default = "default_liveness_window_secs")]
pub liveness_window_secs: u64,
#[serde(default = "default_subscribe_gc_secs")]
pub subscribe_gc_secs: u64,
#[serde(default)]
pub region: String,
#[serde(default)]
pub edge_id: String,
}
fn default_role() -> EdgeRole {
EdgeRole::Home
}
fn default_cache_ttl_secs() -> u64 {
60
}
fn default_max_entries() -> usize {
10_000
}
fn default_max_edges() -> usize {
32
}
fn default_liveness_window_secs() -> u64 {
120
}
fn default_subscribe_gc_secs() -> u64 {
30
}
impl EdgeConfig {
pub fn default_ttl(&self) -> Duration {
Duration::from_secs(self.default_ttl_secs)
}
}
impl Default for EdgeConfig {
fn default() -> Self {
Self {
enabled: false,
role: default_role(),
home_url: String::new(),
auth_token: String::new(),
allow_insecure_home_url: false,
default_ttl_secs: default_cache_ttl_secs(),
max_entries: default_max_entries(),
max_edges: default_max_edges(),
liveness_window_secs: default_liveness_window_secs(),
subscribe_gc_secs: default_subscribe_gc_secs(),
region: String::new(),
edge_id: String::new(),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum EdgeRole {
Home,
Edge,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_role_is_home() {
let cfg = EdgeConfig::default();
assert_eq!(cfg.role, EdgeRole::Home);
assert!(!cfg.enabled);
}
#[test]
fn config_round_trips_through_serde() {
let cfg = EdgeConfig {
enabled: true,
role: EdgeRole::Edge,
home_url: "https://home.svc:9090".into(),
auth_token: "tkn".into(),
default_ttl_secs: 30,
max_entries: 5_000,
max_edges: 0,
region: "eu-west".into(),
edge_id: "edge-a".into(),
..EdgeConfig::default()
};
let json = serde_json::to_string(&cfg).unwrap();
let back: EdgeConfig = serde_json::from_str(&json).unwrap();
assert!(back.enabled);
assert_eq!(back.role, EdgeRole::Edge);
assert_eq!(back.home_url, "https://home.svc:9090");
assert_eq!(back.default_ttl_secs, 30);
assert_eq!(back.default_ttl(), Duration::from_secs(30));
assert_eq!(back.region, "eu-west");
assert_eq!(back.edge_id, "edge-a");
}
#[test]
fn empty_section_deserializes_with_defaults() {
let cfg: EdgeConfig = serde_json::from_str("{}").unwrap();
assert!(!cfg.enabled);
assert_eq!(cfg.role, EdgeRole::Home);
assert_eq!(cfg.home_url, "");
assert_eq!(cfg.auth_token, "");
assert!(!cfg.allow_insecure_home_url);
assert_eq!(cfg.default_ttl_secs, 60);
assert_eq!(cfg.default_ttl(), Duration::from_secs(60));
assert_eq!(cfg.max_entries, 10_000);
assert_eq!(cfg.max_edges, 32);
assert_eq!(cfg.liveness_window_secs, 120);
assert_eq!(cfg.subscribe_gc_secs, 30);
assert_eq!(cfg.region, "");
assert_eq!(cfg.edge_id, "");
}
#[test]
fn partial_toml_section_parses() {
let cfg: EdgeConfig = toml::from_str(
r#"
enabled = true
role = "edge"
home_url = "http://home:9090"
region = "us-east"
default_ttl_secs = 45
"#,
)
.unwrap();
assert!(cfg.enabled);
assert_eq!(cfg.role, EdgeRole::Edge);
assert_eq!(cfg.home_url, "http://home:9090");
assert_eq!(cfg.region, "us-east");
assert_eq!(cfg.default_ttl(), Duration::from_secs(45));
assert_eq!(cfg.liveness_window_secs, 120);
assert_eq!(cfg.subscribe_gc_secs, 30);
assert_eq!(cfg.max_entries, 10_000);
}
}