Add config file impl using new config impl

next
Sayan Nandan 3 years ago
parent afcd8031c2
commit d820ef910d
No known key found for this signature in database
GPG Key ID: 8BC07A0A4D41DD52

@ -124,11 +124,15 @@ impl<'a, T: FromStr + 'a> TryFromConfigSource<T> for Result<String, VarError> {
}
#[derive(Debug)]
/// Since we have conflicting trait implementations, we define a custom `Option<String>` type
pub struct OptString {
base: Option<String>,
}
impl OptString {
pub const fn new(base: Option<String>) -> Self {
Self { base }
}
pub const fn new_null() -> Self {
Self { base: None }
}
@ -137,6 +141,12 @@ impl OptString {
}
}
impl From<Option<String>> for OptString {
fn from(base: Option<String>) -> Self {
Self { base }
}
}
impl FromStr for OptString {
type Err = ();
fn from_str(st: &str) -> Result<Self, Self::Err> {
@ -146,6 +156,24 @@ impl FromStr for OptString {
}
}
impl TryFromConfigSource<OptString> for OptString {
fn is_present(&self) -> bool {
self.base.is_some()
}
fn mutate_failed(self, target: &mut OptString, trip: &mut bool) -> bool {
if let Some(v) = self.base {
target.base = Some(v);
*trip = true;
}
false
}
fn try_parse(self) -> ConfigSourceParseResult<OptString> {
self.base
.map(|v| ConfigSourceParseResult::Okay(OptString { base: Some(v) }))
.unwrap_or(ConfigSourceParseResult::Okay(OptString::new_null()))
}
}
#[derive(Debug)]
/// A high-level configuration set that automatically handles errors, warnings and provides a convenient [`Result`]
/// type that can be used
@ -179,9 +207,14 @@ impl Configset {
pub fn new_cli() -> Self {
Self::_new(Self::EMSG_CLI)
}
/// Create a new configset for a config file
/// Create a new configset for config files
pub fn new_file() -> Self {
Self::_new(Self::EMSG_FILE)
Self {
did_mutate: true,
cfg: ConfigurationSet::default(),
estack: ErrorStack::new(Self::EMSG_FILE),
wstack: WarningStack::new(Self::EMSG_FILE),
}
}
/// Mark the configset mutated
fn mutated(&mut self) {
@ -425,7 +458,7 @@ impl Configset {
"path to TLS cert passphrase",
);
let sslopts = SslOpts::new(key, cert, port, tls_pass.finish());
let sslopts = SslOpts::new(key, cert, port, tls_pass.base);
// now check if TLS only
if tls_only {
let host = self.cfg.ports.get_host();

@ -0,0 +1,159 @@
/*
* Created on Fri Jan 28 2022
*
* 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) 2022, 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 super::cfg2::{ConfigSourceParseResult, Configset, OptString, TryFromConfigSource};
use super::cfgfile::{Config as ConfigFile, ConfigKeyBGSAVE, ConfigKeySnapshot, KeySslOpts};
/// A custom non-null type for config files
pub struct NonNull<T> {
val: T,
}
impl<T> From<T> for NonNull<T> {
fn from(val: T) -> Self {
Self { val }
}
}
impl<T> TryFromConfigSource<T> for NonNull<T> {
fn is_present(&self) -> bool {
true
}
fn mutate_failed(self, target: &mut T, trip: &mut bool) -> bool {
*target = self.val;
*trip = true;
false
}
fn try_parse(self) -> ConfigSourceParseResult<T> {
ConfigSourceParseResult::Okay(self.val)
}
}
pub struct Optional<T> {
base: Option<T>,
}
impl<T> Optional<T> {
pub const fn some(val: T) -> Self {
Self { base: Some(val) }
}
pub const fn none() -> Self {
Self { base: None }
}
}
impl<T> From<Option<T>> for Optional<T> {
fn from(base: Option<T>) -> Self {
Self { base }
}
}
impl<T> TryFromConfigSource<T> for Optional<T> {
fn is_present(&self) -> bool {
self.base.is_some()
}
fn mutate_failed(self, target: &mut T, trip: &mut bool) -> bool {
if let Some(v) = self.base {
*trip = true;
*target = v;
}
false
}
fn try_parse(self) -> ConfigSourceParseResult<T> {
match self.base {
Some(v) => ConfigSourceParseResult::Okay(v),
None => ConfigSourceParseResult::Absent,
}
}
}
pub fn from_file(file: ConfigFile) -> Configset {
let mut set = Configset::new_file();
let ConfigFile {
server,
bgsave,
snapshot,
ssl,
} = file;
// server settings
set.server_tcp(
Optional::some(server.host),
"server.host",
Optional::some(server.port),
"server.port",
);
set.server_maxcon(Optional::from(server.maxclient), "server.maxcon");
set.server_noart(Optional::from(server.noart), "server.noart");
// bgsave settings
if let Some(bgsave) = bgsave {
let ConfigKeyBGSAVE { enabled, every } = bgsave;
set.bgsave_settings(
Optional::from(enabled),
"bgsave.enabled",
Optional::from(every),
"bgsave.every",
);
}
// snapshot settings
if let Some(snapshot) = snapshot {
let ConfigKeySnapshot {
every,
atmost,
failsafe,
} = snapshot;
set.snapshot_settings(
NonNull::from(every),
"snapshot.every",
NonNull::from(atmost),
"snapshot.atmost",
Optional::from(failsafe),
"snapshot.failsafe",
);
}
// TLS settings
if let Some(tls) = ssl {
let KeySslOpts {
key,
chain,
port,
only,
passin,
} = tls;
set.tls_settings(
NonNull::from(key),
"ssl.key",
NonNull::from(chain),
"ssl.chain",
NonNull::from(port),
"ssl.port",
Optional::from(only),
"ssl.only",
OptString::from(passin),
"ssl.passin",
);
}
set
}

@ -42,6 +42,7 @@ mod cfgfile;
mod cfg2;
mod cfgcli2;
mod cfgenv2;
mod cfgfile2;
mod eval;
#[cfg(test)]
mod tests;

Loading…
Cancel
Save