Move config file de into module

This really helps us reduce the grand clutter we created earlier.

Signed-off-by: Sayan Nandan <nandansayan@outlook.com>
next
Sayan Nandan 3 years ago
parent eb037fcd62
commit b5a0e02091
No known key found for this signature in database
GPG Key ID: 5EDED89A1ADA6273

@ -0,0 +1,91 @@
/*
* Created on Sat Oct 02 2021
*
* This file is a part of Skytable
* Skytable (formerly known as TerrabaseDB or Skybase) is a free and open-source
* NoSQL database written by Sayan Nandan ("the Author") with the
* vision to provide flexibility in data modelling without compromising
* on performance, queryability or scalability.
*
* Copyright (c) 2021, Sayan Nandan <ohsayan@outlook.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
use serde::Deserialize;
use std::net::IpAddr;
/// This struct is an _object representation_ used for parsing the TOML file
#[derive(Deserialize, Debug, PartialEq)]
pub struct Config {
/// The `server` key
pub(super) server: ConfigKeyServer,
/// The `bgsave` key
pub(super) bgsave: Option<ConfigKeyBGSAVE>,
/// The snapshot key
pub(super) snapshot: Option<ConfigKeySnapshot>,
/// SSL configuration
pub(super) ssl: Option<KeySslOpts>,
}
/// This struct represents the `server` key in the TOML file
#[derive(Deserialize, Debug, PartialEq)]
pub struct ConfigKeyServer {
/// The host key is any valid IPv4/IPv6 address
pub(super) host: IpAddr,
/// The port key is any valid port
pub(super) port: u16,
/// The noart key is an `Option`al boolean value which is set to true
/// for secure environments to disable terminal artwork
pub(super) noart: Option<bool>,
/// The maximum number of clients
pub(super) maxclient: Option<usize>,
}
/// The BGSAVE section in the config file
#[derive(Deserialize, Debug, PartialEq)]
pub struct ConfigKeyBGSAVE {
/// Whether BGSAVE is enabled or not
///
/// If this key is missing, then we can assume that BGSAVE is enabled
pub(super) enabled: Option<bool>,
/// The duration after which BGSAVE should start
///
/// If this is the only key specified, then it is clear that BGSAVE is enabled
/// and the duration is `every`
pub(super) every: Option<u64>,
}
/// The snapshot section in the TOML file
#[derive(Deserialize, Debug, PartialEq)]
pub struct ConfigKeySnapshot {
/// After how many seconds should the snapshot be created
pub(super) every: u64,
/// The maximum number of snapshots to keep
///
/// If atmost is set to `0`, then all the snapshots will be kept
pub(super) atmost: usize,
/// Prevent writes to the database if snapshotting fails
pub(super) failsafe: Option<bool>,
}
#[derive(Deserialize, Debug, PartialEq)]
pub struct KeySslOpts {
pub(super) key: String,
pub(super) chain: String,
pub(super) port: u16,
pub(super) only: Option<bool>,
pub(super) passin: Option<String>,
}

@ -1,107 +0,0 @@
/*
* Created on Thu Sep 23 2021
*
* This file is a part of Skytable
* Skytable (formerly known as TerrabaseDB or Skybase) is a free and open-source
* NoSQL database written by Sayan Nandan ("the Author") with the
* vision to provide flexibility in data modelling without compromising
* on performance, queryability or scalability.
*
* Copyright (c) 2021, Sayan Nandan <ohsayan@outlook.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
use std::collections::HashMap;
use std::env as std_env;
use std_env::VarError;
type ConfigMap = HashMap<&'static str, Option<String>>;
#[derive(Debug)]
pub enum ConfigStatus {
ParseFailure,
None,
Config(ConfigMap),
}
macro_rules! to_const {
($($(#[$attr:meta])* $v:ident),* $(,)?) => {
$(
$(#[$attr])*
const $v: &str = stringify!($v);
)*
pub fn has_env_config() -> ConfigStatus {
let mut hm = ConfigMap::new();
let mut has_env = false;
$(
match std_env::var($v) {
Ok(var) => {
hm.insert($v, Some(var));
has_env = true;
},
Err(e) => {
match e {
VarError::NotPresent => {},
VarError::NotUnicode {..} => {
return ConfigStatus::ParseFailure;
}
}
}
}
)*
if has_env {
ConfigStatus::Config(hm)
} else {
ConfigStatus::None
}
}
};
}
to_const! {
// system config
/// host addr
SKY_SYSTEM_HOST,
/// port
SKY_SYSTEM_PORT,
/// noart configuration for secure environments
SKY_SYSTEM_NOART,
/// the maximum number of connections
SKY_SYSTEM_MAXCON,
// bgsave
/// enabled/disabled flag for bgsave
SKY_BGSAVE_ENABLED,
/// bgsave interval
SKY_BGSAVE_EVERY,
// snapshot
/// snapshot interval
SKY_SNAPSHOT_EVERY,
/// maximum number of snapshots
SKY_SNAPSHOT_ATMOST,
/// flag to disable writes if snapshot fails
SKY_SNAPSHOT_FAILSAFE,
// TLS
/// the tls private key
SKY_TLS_KEY,
/// the tls cert
SKY_TLS_CERT,
/// the tls port
SKY_TLS_PORT,
/// the tls-only flag
SKY_TLS_ONLY,
/// the tls password stream
SKY_TLS_PASSIN
}

@ -32,38 +32,22 @@ use std::error::Error;
use std::fmt; use std::fmt;
use std::fs; use std::fs;
use std::net::{IpAddr, Ipv4Addr}; use std::net::{IpAddr, Ipv4Addr};
mod env; // modules
mod cfgfile;
#[cfg(test)] #[cfg(test)]
mod tests; mod tests;
const DEFAULT_IPV4: IpAddr = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)); const DEFAULT_IPV4: IpAddr = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
const DEFAULT_SSL_PORT: u16 = 2004; const DEFAULT_SSL_PORT: u16 = 2004;
/// This struct is an _object representation_ used for parsing the TOML file macro_rules! cli_parse_or_default_or_err {
#[derive(Deserialize, Debug, PartialEq)] ($parsewhat:expr, $default:expr, $except:expr $(,)?) => {
pub struct Config { match $parsewhat.map(|v| v.parse()) {
/// The `server` key Some(Ok(v)) => v,
server: ConfigKeyServer, Some(Err(_)) => return Err(ConfigError::CliArgErr($except)),
/// The `bgsave` key None => $default,
bgsave: Option<ConfigKeyBGSAVE>, }
/// The snapshot key };
snapshot: Option<ConfigKeySnapshot>,
/// SSL configuration
ssl: Option<KeySslOpts>,
}
/// The BGSAVE section in the config file
#[derive(Deserialize, Debug, PartialEq)]
pub struct ConfigKeyBGSAVE {
/// Whether BGSAVE is enabled or not
///
/// If this key is missing, then we can assume that BGSAVE is enabled
enabled: Option<bool>,
/// The duration after which BGSAVE should start
///
/// If this is the only key specified, then it is clear that BGSAVE is enabled
/// and the duration is `every`
every: Option<u64>,
} }
/// The BGSAVE configuration /// The BGSAVE configuration
@ -99,33 +83,6 @@ impl BGSave {
} }
} }
/// This struct represents the `server` key in the TOML file
#[derive(Deserialize, Debug, PartialEq)]
pub struct ConfigKeyServer {
/// The host key is any valid IPv4/IPv6 address
host: IpAddr,
/// The port key is any valid port
port: u16,
/// The noart key is an `Option`al boolean value which is set to true
/// for secure environments to disable terminal artwork
noart: Option<bool>,
/// The maximum number of clients
maxclient: Option<usize>,
}
/// The snapshot section in the TOML file
#[derive(Deserialize, Debug, PartialEq)]
pub struct ConfigKeySnapshot {
/// After how many seconds should the snapshot be created
every: u64,
/// The maximum number of snapshots to keep
///
/// If atmost is set to `0`, then all the snapshots will be kept
atmost: usize,
/// Prevent writes to the database if snapshotting fails
failsafe: Option<bool>,
}
/// Port configuration /// Port configuration
/// ///
/// This enumeration determines whether the ports are: /// This enumeration determines whether the ports are:
@ -174,15 +131,6 @@ impl PortConfig {
} }
} }
#[derive(Deserialize, Debug, PartialEq)]
pub struct KeySslOpts {
key: String,
chain: String,
port: u16,
only: Option<bool>,
passin: Option<String>,
}
#[derive(Deserialize, Debug, PartialEq)] #[derive(Deserialize, Debug, PartialEq)]
pub struct SslOpts { pub struct SslOpts {
pub key: String, pub key: String,
@ -282,7 +230,7 @@ impl ParsedConfig {
} }
/// Create a `ParsedConfig` instance from a `Config` object, which is a parsed /// Create a `ParsedConfig` instance from a `Config` object, which is a parsed
/// TOML file (represented as an object) /// TOML file (represented as an object)
fn from_config(cfg_info: Config) -> Self { fn from_config(cfg_info: cfgfile::Config) -> Self {
ParsedConfig { ParsedConfig {
noart: option_unwrap_or!(cfg_info.server.noart, false), noart: option_unwrap_or!(cfg_info.server.noart, false),
bgsave: if let Some(bgsave) = cfg_info.bgsave { bgsave: if let Some(bgsave) = cfg_info.bgsave {
@ -464,48 +412,26 @@ pub fn get_config_file_or_return_cfg() -> Result<ConfigType<ParsedConfig, String
// were supplied // were supplied
if cli_has_overrideable_args { if cli_has_overrideable_args {
// This means that there are some command-line args that we need to parse // This means that there are some command-line args that we need to parse
let port: u16 = match port { let port: u16 = cli_parse_or_default_or_err!(
Some(p) => match p.parse() { port,
Ok(parsed) => parsed, 2003,
Err(_) => { "Invalid value for `--port`. Expected an unsigned 16-bit integer"
return Err(ConfigError::CliArgErr( );
"Invalid value for `--port`. Expected an unsigned 16-bit integer", let host: IpAddr = cli_parse_or_default_or_err!(
)) host,
} DEFAULT_IPV4,
}, "Invalid value for `--host`. Expected a valid IPv4 or IPv6 address"
None => 2003, );
}; let sslport: u16 = cli_parse_or_default_or_err!(
let host: IpAddr = match host { sslport,
Some(h) => match h.parse() { DEFAULT_SSL_PORT,
Ok(h) => h, "Invalid value for `--sslport`. Expected a valid unsigned 16-bit integer"
Err(_) => { );
return Err(ConfigError::CliArgErr( let maxcon: usize = cli_parse_or_default_or_err!(
"Invalid value for `--host`. Expected a valid IPv4 or IPv6 address", maxcon,
)); MAXIMUM_CONNECTION_LIMIT,
} "Invalid value for `--maxcon`. Expected a valid positive integer"
}, );
None => "127.0.0.1".parse().unwrap(),
};
let sslport: u16 = match sslport.map(|port| port.parse()) {
Some(Ok(port)) => port,
Some(Err(_)) => {
return Err(ConfigError::CliArgErr(
"Invalid value for `--sslport`. Expected a valid unsigned 16-bit integer",
))
}
None => DEFAULT_SSL_PORT,
};
let maxcon: usize = match maxcon {
Some(limit) => match limit.parse() {
Ok(l) => l,
Err(_) => {
return Err(ConfigError::CliArgErr(
"Invalid value for `--maxcon`. Expected a valid positive integer",
));
}
},
None => MAXIMUM_CONNECTION_LIMIT,
};
let bgsave = if nosave { let bgsave = if nosave {
if saveduration.is_some() { if saveduration.is_some() {
// If there is both `nosave` and `saveduration` - the arguments aren't logically correct! // If there is both `nosave` and `saveduration` - the arguments aren't logically correct!

@ -290,3 +290,33 @@ macro_rules! ucidx {
*($base.as_ptr().add($idx as usize)) *($base.as_ptr().add($idx as usize))
}; };
} }
#[macro_export]
macro_rules! def {
(
$(#[$attr:meta])*
$vis:vis struct $ident:ident {
$(
$(#[$fattr:meta])*
$field:ident: $ty:ty = $defexpr:expr
),* $(,)?
}
) => {
$(#[$attr])*
$vis struct $ident {
$(
$(#[$fattr])*
$field: $ty,
)*
}
impl ::core::default::Default for $ident {
fn default() -> Self {
Self {
$(
$field: $defexpr,
)*
}
}
}
};
}

Loading…
Cancel
Save