|
|
|
@ -23,25 +23,97 @@
|
|
|
|
|
|
|
|
|
|
use libtdb::TResult;
|
|
|
|
|
use serde::Deserialize;
|
|
|
|
|
use std::fs;
|
|
|
|
|
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
|
|
|
|
use tokio::net::ToSocketAddrs;
|
|
|
|
|
use toml;
|
|
|
|
|
|
|
|
|
|
/// Gets a `toml` file from `WORKSPACEROOT/examples/config-files`
|
|
|
|
|
#[cfg(test)]
|
|
|
|
|
fn get_toml_from_examples_dir(filename: String) -> TResult<String> {
|
|
|
|
|
use std::path;
|
|
|
|
|
let curdir = std::env::current_dir().unwrap();
|
|
|
|
|
let workspaceroot = curdir.ancestors().nth(1).unwrap();
|
|
|
|
|
let mut fileloc = path::PathBuf::from(workspaceroot);
|
|
|
|
|
fileloc.push("examples");
|
|
|
|
|
fileloc.push("config-files");
|
|
|
|
|
fileloc.push(filename);
|
|
|
|
|
Ok(fs::read_to_string(fileloc)?)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Deserialize, Debug, PartialEq)]
|
|
|
|
|
struct Config {
|
|
|
|
|
pub struct Config {
|
|
|
|
|
server: ServerConfig,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Deserialize, Debug, PartialEq)]
|
|
|
|
|
struct ServerConfig {
|
|
|
|
|
pub struct ServerConfig {
|
|
|
|
|
host: IpAddr,
|
|
|
|
|
port: u16,
|
|
|
|
|
noart: Option<bool>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Config {
|
|
|
|
|
pub fn new(file: String) -> TResult<Self> {
|
|
|
|
|
let res: Config = toml::from_str(&file)?;
|
|
|
|
|
Ok(res)
|
|
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
|
pub struct ParsedConfig {
|
|
|
|
|
host: IpAddr,
|
|
|
|
|
port: u16,
|
|
|
|
|
noart: bool,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl ParsedConfig {
|
|
|
|
|
/// Create a new `ParsedConfig` from a given file in `location`
|
|
|
|
|
pub fn new_from_file(location: String) -> TResult<Self> {
|
|
|
|
|
let file = fs::read_to_string(location)?;
|
|
|
|
|
Ok(ParsedConfig::from_config(toml::from_str(&file)?))
|
|
|
|
|
}
|
|
|
|
|
fn from_config(cfg: Config) -> Self {
|
|
|
|
|
ParsedConfig {
|
|
|
|
|
host: cfg.server.host,
|
|
|
|
|
port: cfg.server.port,
|
|
|
|
|
noart: if let Some(noart) = cfg.server.noart {
|
|
|
|
|
noart
|
|
|
|
|
} else {
|
|
|
|
|
false
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
pub fn new_from_toml_str(tomlstr: String) -> TResult<Self> {
|
|
|
|
|
Ok(ParsedConfig::from_config(toml::from_str(&tomlstr)?))
|
|
|
|
|
}
|
|
|
|
|
/// Create a new `ParsedConfig` with the default `host` and `noart` settngs
|
|
|
|
|
/// and a supplied `port`
|
|
|
|
|
pub fn default_with_port(port: u16) -> Self {
|
|
|
|
|
ParsedConfig {
|
|
|
|
|
host: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
|
|
|
|
|
port,
|
|
|
|
|
noart: false,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/// Create a new `ParsedConfig` with the default `port` and `noart` settngs
|
|
|
|
|
/// and a supplied `host`
|
|
|
|
|
pub fn default_with_host(host: IpAddr) -> Self {
|
|
|
|
|
ParsedConfig::new(host, 2003, false)
|
|
|
|
|
}
|
|
|
|
|
/// Create a new `ParsedConfig` with all the fields
|
|
|
|
|
pub fn new(host: IpAddr, port: u16, noart: bool) -> Self {
|
|
|
|
|
ParsedConfig { host, port, noart }
|
|
|
|
|
}
|
|
|
|
|
/// Create a default `ParsedConfig` with:
|
|
|
|
|
/// - `host`: 127.0.0.1
|
|
|
|
|
/// - `port` : 2003
|
|
|
|
|
/// - `noart` : false
|
|
|
|
|
pub fn default() -> Self {
|
|
|
|
|
ParsedConfig {
|
|
|
|
|
host: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
|
|
|
|
|
port: 2003,
|
|
|
|
|
noart: false,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
pub fn get_host_port_tuple(self) -> impl ToSocketAddrs {
|
|
|
|
|
((self.host), self.port)
|
|
|
|
|
}
|
|
|
|
|
pub fn is_artful(&self) -> bool {
|
|
|
|
|
!self.noart
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -54,15 +126,13 @@ fn test_config_toml_okayport() {
|
|
|
|
|
port = 2003
|
|
|
|
|
"#
|
|
|
|
|
.to_owned();
|
|
|
|
|
let cfg = Config::new(file).unwrap();
|
|
|
|
|
let cfg = ParsedConfig::new_from_toml_str(file).unwrap();
|
|
|
|
|
assert_eq!(
|
|
|
|
|
cfg,
|
|
|
|
|
Config {
|
|
|
|
|
server: ServerConfig {
|
|
|
|
|
port: 2003,
|
|
|
|
|
host: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
|
|
|
|
|
noart: None,
|
|
|
|
|
}
|
|
|
|
|
ParsedConfig {
|
|
|
|
|
port: 2003,
|
|
|
|
|
host: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
|
|
|
|
|
noart: false,
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
@ -75,44 +145,49 @@ fn test_config_toml_badport() {
|
|
|
|
|
port = 20033002
|
|
|
|
|
"#
|
|
|
|
|
.to_owned();
|
|
|
|
|
let cfg = Config::new(file);
|
|
|
|
|
let cfg = ParsedConfig::new_from_file(file);
|
|
|
|
|
assert!(cfg.is_err());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
#[cfg(test)]
|
|
|
|
|
fn test_config_file_ok() {
|
|
|
|
|
let fileloc = "../examples/config-files/tdb.toml";
|
|
|
|
|
let file = std::fs::read_to_string(fileloc).unwrap();
|
|
|
|
|
let cfg: Config = Config::new(file).unwrap();
|
|
|
|
|
assert_eq!(
|
|
|
|
|
cfg,
|
|
|
|
|
Config {
|
|
|
|
|
server: ServerConfig {
|
|
|
|
|
port: 2003,
|
|
|
|
|
host: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
|
|
|
|
|
noart: None,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
let file = get_toml_from_examples_dir("tdb.toml".to_owned()).unwrap();
|
|
|
|
|
let cfg = ParsedConfig::new_from_toml_str(file).unwrap();
|
|
|
|
|
assert_eq!(cfg, ParsedConfig::default());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
#[cfg(test)]
|
|
|
|
|
fn test_config_file_err() {
|
|
|
|
|
let fileloc = "../examples/config-files/badcfg.toml";
|
|
|
|
|
let file = std::fs::read_to_string(fileloc).unwrap();
|
|
|
|
|
let cfg = Config::new(file);
|
|
|
|
|
let file = get_toml_from_examples_dir("tdb.toml".to_owned()).unwrap();
|
|
|
|
|
let cfg = ParsedConfig::new_from_file(file);
|
|
|
|
|
assert!(cfg.is_err());
|
|
|
|
|
}
|
|
|
|
|
use clap::{load_yaml, App};
|
|
|
|
|
|
|
|
|
|
/// Get the command line arguments
|
|
|
|
|
pub fn get_config_file() -> Option<String> {
|
|
|
|
|
pub enum ConfigType<T> {
|
|
|
|
|
Def(T),
|
|
|
|
|
Custom(T),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// # Return a `ConfigType<ParsedConfig>`
|
|
|
|
|
///
|
|
|
|
|
/// This parses a configuration file if it is supplied as a command line argument
|
|
|
|
|
/// or it returns the default configuration. **If** the configuration file
|
|
|
|
|
/// contains an error, then this returns it as an `Err` variant
|
|
|
|
|
pub fn get_config_file_or_return_cfg() -> TResult<ConfigType<ParsedConfig>> {
|
|
|
|
|
let cfg_layout = load_yaml!("../cli.yml");
|
|
|
|
|
let matches = App::from_yaml(cfg_layout).get_matches();
|
|
|
|
|
let filename = matches.value_of("config");
|
|
|
|
|
filename.map(|fname| fname.to_owned())
|
|
|
|
|
if let Some(filename) = filename {
|
|
|
|
|
match ParsedConfig::new_from_file(filename.to_owned()) {
|
|
|
|
|
Ok(cfg) => return Ok(ConfigType::Custom(cfg)),
|
|
|
|
|
Err(e) => return Err(e),
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
Ok(ConfigType::Def(ParsedConfig::default()))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
@ -123,33 +198,21 @@ fn test_args() {
|
|
|
|
|
let matches = App::from_yaml(cfg_layout).get_matches_from(cmdlineargs);
|
|
|
|
|
let filename = matches.value_of("config").unwrap();
|
|
|
|
|
assert_eq!("../examples/config-files/tdb.toml", filename);
|
|
|
|
|
let cfg = Config::new(std::fs::read_to_string(filename).unwrap()).unwrap();
|
|
|
|
|
assert_eq!(
|
|
|
|
|
cfg,
|
|
|
|
|
Config {
|
|
|
|
|
server: ServerConfig {
|
|
|
|
|
port: 2003,
|
|
|
|
|
host: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
|
|
|
|
|
noart: None,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
let cfg = ParsedConfig::new_from_toml_str(std::fs::read_to_string(filename).unwrap()).unwrap();
|
|
|
|
|
assert_eq!(cfg, ParsedConfig::default());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
#[cfg(test)]
|
|
|
|
|
fn test_config_file_noart() {
|
|
|
|
|
let fileloc = "../examples/config-files/secure-noart.toml";
|
|
|
|
|
let file = std::fs::read_to_string(fileloc).unwrap();
|
|
|
|
|
let cfg: Config = Config::new(file).unwrap();
|
|
|
|
|
let file = get_toml_from_examples_dir("secure-noart.toml".to_owned()).unwrap();
|
|
|
|
|
let cfg = ParsedConfig::new_from_toml_str(file).unwrap();
|
|
|
|
|
assert_eq!(
|
|
|
|
|
cfg,
|
|
|
|
|
Config {
|
|
|
|
|
server: ServerConfig {
|
|
|
|
|
port: 2003,
|
|
|
|
|
host: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
|
|
|
|
|
noart: Some(true),
|
|
|
|
|
}
|
|
|
|
|
ParsedConfig {
|
|
|
|
|
port: 2003,
|
|
|
|
|
host: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
|
|
|
|
|
noart: true,
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
@ -157,17 +220,14 @@ fn test_config_file_noart() {
|
|
|
|
|
#[test]
|
|
|
|
|
#[cfg(test)]
|
|
|
|
|
fn test_config_file_ipv6() {
|
|
|
|
|
let fileloc = "../examples/config-files/ipv6.toml";
|
|
|
|
|
let file = std::fs::read_to_string(fileloc).unwrap();
|
|
|
|
|
let cfg: Config = Config::new(file).unwrap();
|
|
|
|
|
let file = get_toml_from_examples_dir("ipv6.toml".to_owned()).unwrap();
|
|
|
|
|
let cfg = ParsedConfig::new_from_toml_str(file).unwrap();
|
|
|
|
|
assert_eq!(
|
|
|
|
|
cfg,
|
|
|
|
|
Config {
|
|
|
|
|
server: ServerConfig {
|
|
|
|
|
port: 2003,
|
|
|
|
|
host: IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0x1)),
|
|
|
|
|
noart: None,
|
|
|
|
|
}
|
|
|
|
|
ParsedConfig {
|
|
|
|
|
port: 2003,
|
|
|
|
|
host: IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0x1)),
|
|
|
|
|
noart: false,
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|