1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
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 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,
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 serde_json;
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));
}
}
}