use config_file_handler::{self, FileHandler};
use std::collections::HashSet;
use std::ffi::OsString;
use std::net::{IpAddr, SocketAddr};
#[cfg(test)]
use std::path::PathBuf;
#[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Clone)]
pub struct Config {
pub hard_coded_contacts: Vec<SocketAddr>,
pub tcp_acceptor_port: Option<u16>,
pub force_acceptor_port_in_ext_ep: bool,
pub service_discovery_port: Option<u16>,
pub service_discovery_listener_port: Option<u16>,
pub bootstrap_cache_name: Option<String>,
pub whitelisted_node_ips: Option<HashSet<IpAddr>>,
pub whitelisted_client_ips: Option<HashSet<IpAddr>>,
pub network_name: Option<String>,
pub dev: Option<DevConfig>,
}
#[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Clone, Default)]
pub struct DevConfig {
pub disable_external_reachability_requirement: bool,
}
impl Default for Config {
fn default() -> Config {
Config {
hard_coded_contacts: vec![],
tcp_acceptor_port: None,
force_acceptor_port_in_ext_ep: false,
service_discovery_port: None,
service_discovery_listener_port: None,
bootstrap_cache_name: None,
whitelisted_node_ips: None,
whitelisted_client_ips: None,
network_name: None,
dev: None,
}
}
}
pub fn read_config_file() -> ::Res<Config> {
let file_handler = FileHandler::new(&get_file_name()?, false)?;
let cfg = file_handler.read_file()?;
Ok(cfg)
}
#[cfg(test)]
#[allow(dead_code)]
pub fn write_config_file(hard_coded_contacts: Option<Vec<SocketAddr>>) -> ::Res<PathBuf> {
use std::io::Write;
let mut config = Config::default();
if let Some(contacts) = hard_coded_contacts {
config.hard_coded_contacts = contacts;
}
let mut config_path = config_file_handler::current_bin_dir()?;
config_path.push(get_file_name()?);
let mut file = ::std::fs::File::create(&config_path)?;
write!(
&mut file,
"{}",
unwrap!(serde_json::to_string_pretty(&config))
)?;
file.sync_all()?;
Ok(config_path)
}
fn get_file_name() -> ::Res<OsString> {
let mut name = config_file_handler::exe_file_stem()?;
name.push(".crust.config");
Ok(name)
}
#[cfg(test)]
mod tests {
use super::Config;
use serde_json;
use std::io::Read;
use std::path::Path;
#[test]
fn parse_sample_config_file() {
let path = Path::new("installer/sample.config").to_path_buf();
let mut file = match ::std::fs::File::open(path) {
Ok(file) => file,
Err(what) => panic!(format!("CrustError opening sample.config: {:?}", what)),
};
let mut encoded_contents = String::new();
if let Err(what) = file.read_to_string(&mut encoded_contents) {
panic!(format!("CrustError reading sample.config: {:?}", what));
}
if let Err(what) = serde_json::from_str::<Config>(&encoded_contents) {
panic!(format!("CrustError parsing sample.config: {:?}", what));
}
}
}