use std::{
error::Error,
fmt,
sync::{Arc, RwLock},
};
use crate::env::{EnvironmentConfig, NetworkEnvOverrides};
pub mod http;
pub mod qos;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct NetworkConfig {
pub http: http::HttpConfig,
pub qos: qos::QosPolicy,
}
impl NetworkConfig {
pub fn from_overrides(overrides: &NetworkEnvOverrides) -> Result<Self, NetworkConfigError> {
Ok(Self {
http: http::HttpConfig::from_overrides(overrides).map_err(NetworkConfigError::Http)?,
qos: qos::QosPolicy::from_overrides(overrides).map_err(NetworkConfigError::Qos)?,
})
}
}
#[derive(Debug, Clone)]
pub struct NetworkRuntime {
inner: Arc<RwLock<NetworkConfig>>,
qos: qos::QosRuntime,
}
impl NetworkRuntime {
pub fn from_config(config: NetworkConfig) -> Self {
Self {
inner: Arc::new(RwLock::new(config)),
qos: qos::QosRuntime::default(),
}
}
pub fn from_overrides(overrides: &NetworkEnvOverrides) -> Result<Self, NetworkConfigError> {
NetworkConfig::from_overrides(overrides).map(Self::from_config)
}
pub fn current(&self) -> NetworkConfig {
self.inner
.read()
.unwrap_or_else(|poisoned| poisoned.into_inner())
.clone()
}
pub fn qos_runtime(&self) -> qos::QosRuntime {
self.qos.clone()
}
pub fn refresh_from_overrides(
&self,
overrides: &NetworkEnvOverrides,
) -> Result<NetworkConfig, NetworkConfigError> {
let config = NetworkConfig::from_overrides(overrides)?;
*self
.inner
.write()
.unwrap_or_else(|poisoned| poisoned.into_inner()) = config.clone();
Ok(config)
}
pub fn refresh_from_environment(
&self,
environment: &EnvironmentConfig,
) -> Result<NetworkConfig, NetworkConfigError> {
self.refresh_from_overrides(&environment.network)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum NetworkConfigError {
Http(http::HttpConfigError),
Qos(qos::QosPolicyError),
}
impl fmt::Display for NetworkConfigError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Http(error) => write!(formatter, "invalid HTTP configuration: {error}"),
Self::Qos(error) => write!(formatter, "invalid QoS policy: {error}"),
}
}
}
impl Error for NetworkConfigError {}
#[cfg(test)]
#[path = "mod_tests.rs"]
mod tests;