extern crate config;
extern crate serde;
use config::{Config, ConfigError, Environment, File};
use std::collections::{HashMap, HashSet};
use std::env;
#[derive(Debug, Default, Deserialize)]
pub struct Settings {
pub dev_mode: bool,
pub log_level: String,
pub test_server_duration: u64,
pub executor: Option<Executor>,
pub features: HashSet<Feature>,
pub services: HashSet<Service>,
pub coordinator: Vec<HashMap<Coordinator, CoordinatorVariant>>,
pub component: Vec<HashMap<Component, ComponentVariant>>,
pub additional: Vec<HashMap<Additional, AdditionalVariant>>,
}
#[derive(Debug, Deserialize, Copy, Clone, Eq, PartialEq, Hash)]
pub enum Feature {
EchoServer,
Forwarder,
}
#[derive(Debug, Deserialize, Copy, Clone, Eq, PartialEq, Hash)]
pub enum Service {
EchoServer,
ChatServer,
MonitorService,
AliceService,
}
#[derive(Debug, Deserialize)]
pub struct Executor {
pub executors: Option<usize>,
pub queue_size: Option<usize>,
pub time_slice: Option<usize>,
}
#[derive(Debug, Deserialize, Copy, Clone, Eq, PartialEq, Hash)]
pub enum Coordinator {
EchoCoordinator,
ChatCoordinator,
MonitorCoordinator,
AliceCoordinator,
}
#[derive(Debug, Deserialize, Clone)]
#[serde(untagged)]
pub enum CoordinatorVariant {
SimpleTcpConfig {
tcp_address: String,
kv: Option<HashMap<String, String>>,
},
}
#[derive(Debug, Deserialize, Copy, Clone, Eq, PartialEq, Hash)]
pub enum Component {
EchoConsumer,
EchoProducer,
ChatConsumer,
ChatProducer,
}
#[derive(Debug, Deserialize, Clone, Eq, PartialEq)]
#[serde(untagged)]
pub enum ComponentVariant {
SimpleConfig {
enabled: bool,
kv: Option<HashMap<String, String>>,
},
}
#[derive(Debug, Deserialize, Copy, Clone, Eq, PartialEq, Hash)]
pub enum Additional {
Forwarder,
}
#[derive(Debug, Deserialize, Copy, Clone, Eq, PartialEq, Hash)]
#[allow(non_camel_case_types)]
pub enum Field {
daisy_chain,
fanout_fanin,
chaos_monkey,
forwarding_multiplier,
machines,
messages,
iterations,
timeout,
fanin_capacity,
inflection_value,
unbound_queue,
}
pub type FieldMap = HashMap<Field, usize>;
#[derive(Debug, Deserialize, Clone, Eq, PartialEq)]
#[serde(untagged)]
pub enum AdditionalVariant {
Forwarder {
run: Vec<Field>,
default: FieldMap,
daisy_chain: Option<FieldMap>,
fanout_fanin: Option<FieldMap>,
chaos_monkey: Option<FieldMap>,
},
}
impl Settings {
pub fn new() -> Result<Self, ConfigError> {
let mut s = Config::new();
s.merge(File::with_name("config/default"))?;
let env = env::var("RUN_MODE").unwrap_or_else(|_| "development".into());
s.merge(File::with_name(&format!("config/{}", env)).required(false))?;
s.merge(File::with_name("config/local").required(false))?;
s.merge(Environment::with_prefix("app"))?;
s.try_into()
}
}
#[derive(Debug, Default)]
pub struct SimpleConfig {
pub enabled: bool,
pub kv: Option<HashMap<String, String>>,
}
impl SimpleConfig {
pub fn from(v: &ComponentVariant) -> Self {
match v.clone() {
ComponentVariant::SimpleConfig { enabled, kv } => Self { enabled, kv },
}
}
}