added configuration through args support to config manager and network manager.
This commit is contained in:
parent
950ee1919b
commit
8c167ad603
|
|
@ -15,7 +15,7 @@ crossbeam-channel = "0.5.0"
|
|||
crossbeam-queue = "0.3.1"
|
||||
parking_lot = "0.11.1"
|
||||
dashmap = "4.0.2"
|
||||
rayon = "1.3.1"
|
||||
rayon = "1.2.0"
|
||||
zeroize = "1.1.0"
|
||||
crossterm = "0.19.0"
|
||||
log = "0.4"
|
||||
|
|
@ -23,6 +23,6 @@ url = "2.2.0"
|
|||
futures = "0.3.16"
|
||||
serde_json = "1.0"
|
||||
openssl = "0.10"
|
||||
uuid = {version = "0.8", features = ["serde", "v4"]}
|
||||
uuid = {version = "1.1.2", features = ["serde", "v4"]}
|
||||
tokio = { version = "1.9.0", features = ["full"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
|
@ -19,8 +19,8 @@ name = "server"
|
|||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
clap = "3.2.5"
|
||||
uuid = {version = "0.8", features = ["serde", "v4"]}
|
||||
clap = {version = "3.2.5", features = ["derive"]}
|
||||
uuid = {version = "1.1.2", features = ["serde", "v4"]}
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
crossbeam = "0.8.0"
|
||||
|
|
@ -34,7 +34,7 @@ actix = "0.13"
|
|||
rhai = {version = "1.7.0"}
|
||||
mlua = { version = "0.8.1", features=["lua54", "async", "serde", "macros", "vendored"] }
|
||||
libloading = "0.7"
|
||||
toml = "0.4.2"
|
||||
toml = "0.5.9"
|
||||
aquamarine = "0.1.11"
|
||||
tokio-stream = "0.1.9"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,42 +0,0 @@
|
|||
use clap::{App, Arg, ArgMatches, value_parser};
|
||||
|
||||
pub(crate) fn get_args() -> ArgMatches {
|
||||
App::new("Rust Chat Server")
|
||||
.author("Michael Bailey & Mitchel Hardie")
|
||||
.version("0.1.0")
|
||||
.about("A chat server written in rust, with a custom json protocol, based on serde and actix")
|
||||
.arg(
|
||||
Arg::new("port")
|
||||
.short('p')
|
||||
.long("port")
|
||||
.takes_value(true)
|
||||
.value_parser(value_parser!(u16))
|
||||
.default_value("5600")
|
||||
.help("overrides the default port")
|
||||
)
|
||||
.arg(
|
||||
Arg::new("server name")
|
||||
.short('n')
|
||||
.long("name")
|
||||
.takes_value(true)
|
||||
.help("overrides the default port of the server")
|
||||
)
|
||||
.arg(
|
||||
Arg::new("server owner")
|
||||
.short('o')
|
||||
.long("owner")
|
||||
.takes_value(true)
|
||||
.help("overrides the owner of the server")
|
||||
)
|
||||
.arg(
|
||||
Arg::new("config file")
|
||||
.short('c')
|
||||
.long("config_file")
|
||||
.takes_value(true)
|
||||
.help("overrides the default config file location")
|
||||
)
|
||||
.after_help("This is a chat server made to test out writing a full application in rust \
|
||||
It has evolved over time to use different frameworks\
|
||||
It is currently using actix")
|
||||
.get_matches()
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
use clap::Parser;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[clap(author, version, about, long_about = None)]
|
||||
pub struct Arguments {
|
||||
#[clap(short, long, value_parser = clap::value_parser!(u16).range(1..))]
|
||||
pub port: Option<u16>,
|
||||
|
||||
#[clap(short, long, value_parser)]
|
||||
pub name: Option<String>,
|
||||
|
||||
#[clap(short, long, value_parser)]
|
||||
pub owner: Option<String>,
|
||||
}
|
||||
|
|
@ -1,15 +1,17 @@
|
|||
use actix::{Actor, Addr};
|
||||
|
||||
use crate::config_manager::ConfigManager;
|
||||
use crate::config_manager::{arg_parser::Arguments, ConfigManager};
|
||||
|
||||
pub(super) struct Builder {
|
||||
pub(super) file_path: String,
|
||||
pub(super) args: Option<Arguments>,
|
||||
}
|
||||
|
||||
impl Builder {
|
||||
pub(super) fn new() -> Self {
|
||||
Self {
|
||||
file_path: "./config_file.toml".to_owned(),
|
||||
args: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -23,6 +25,15 @@ impl Builder {
|
|||
self.file_path = path.into();
|
||||
}
|
||||
|
||||
pub fn args(mut self, args: Arguments) -> Self {
|
||||
self.args.replace(args);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_args(&mut self, args: Arguments) {
|
||||
self.args.replace(args);
|
||||
}
|
||||
|
||||
pub(super) fn build(self) -> Addr<ConfigManager> {
|
||||
ConfigManager::from(self).start()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,17 +6,22 @@ use std::{
|
|||
};
|
||||
|
||||
use actix::{Actor, Addr, Context, Handler, Recipient};
|
||||
use clap::Parser;
|
||||
use toml::Value;
|
||||
|
||||
use crate::{
|
||||
config_manager::{
|
||||
arg_parser::Arguments,
|
||||
builder::Builder,
|
||||
get_args,
|
||||
messages::{
|
||||
ConfigManagerDataMessage, ConfigManagerDataResponse,
|
||||
ConfigManagerOutput,
|
||||
},
|
||||
types::{ConfigError, ConfigValue},
|
||||
types::{
|
||||
ConfigError,
|
||||
ConfigValue::{Dict, Number, String as ConfigString},
|
||||
},
|
||||
ConfigValue,
|
||||
},
|
||||
prelude::messages::ObservableMessage,
|
||||
};
|
||||
|
|
@ -36,12 +41,8 @@ pub(crate) struct ConfigManager {
|
|||
impl ConfigManager {
|
||||
pub fn shared() -> Addr<Self> {
|
||||
INIT.call_once(|| {
|
||||
let args = get_args();
|
||||
let mut builder = Self::create();
|
||||
|
||||
args.get_one::<String>("config file")
|
||||
.map(|p| builder.set_config_path(p));
|
||||
unsafe { SHARED = Some(builder.build()) }
|
||||
let builder = Self::create().args(Arguments::parse()).build();
|
||||
unsafe { SHARED = Some(builder) }
|
||||
});
|
||||
unsafe { SHARED.clone().unwrap() }
|
||||
}
|
||||
|
|
@ -55,7 +56,6 @@ impl ConfigManager {
|
|||
impl ConfigManager {
|
||||
pub fn get_value(&self, key: String) -> Result<ConfigValue, ConfigError> {
|
||||
use ConfigError::{NoKey, NoValue};
|
||||
use ConfigValue::Dict;
|
||||
|
||||
if let Dict(dict) = &self.root {
|
||||
let opt_value = dict.get(&key);
|
||||
|
|
@ -75,8 +75,6 @@ impl ConfigManager {
|
|||
) -> Result<ConfigValue, ConfigError> {
|
||||
use ConfigError::IncompatableValue;
|
||||
|
||||
use ConfigValue::Dict;
|
||||
|
||||
if let (Dict(stored), Dict(root)) = (&mut self.stored, &mut self.root) {
|
||||
stored.insert(key.clone(), value.clone());
|
||||
root.insert(key.clone(), value.clone());
|
||||
|
|
@ -93,7 +91,6 @@ impl ConfigManager {
|
|||
value: ConfigValue,
|
||||
) -> Result<ConfigValue, ConfigError> {
|
||||
use ConfigError::IncompatableValue;
|
||||
use ConfigValue::Dict;
|
||||
|
||||
if let Dict(root) = &mut self.root {
|
||||
root.insert(key, value.clone());
|
||||
|
|
@ -139,6 +136,8 @@ impl Handler<ConfigManagerDataMessage> for ConfigManager {
|
|||
|
||||
impl From<Builder> for ConfigManager {
|
||||
fn from(builder: Builder) -> Self {
|
||||
println!("got args: {:#?}", builder.args);
|
||||
|
||||
let mut file = OpenOptions::new()
|
||||
.write(true)
|
||||
.read(true)
|
||||
|
|
@ -155,11 +154,34 @@ impl From<Builder> for ConfigManager {
|
|||
.parse::<Value>()
|
||||
.map(|v| v.into())
|
||||
.ok()
|
||||
.unwrap_or_else(|| ConfigValue::Dict(BTreeMap::new()));
|
||||
.unwrap_or_else(|| Dict(BTreeMap::new()));
|
||||
|
||||
let mut root = stored.clone();
|
||||
if let Dict(root) = &mut root {
|
||||
builder.args.map(|v| {
|
||||
v.port.map(|p| {
|
||||
root.insert("Network.Port".to_owned(), Number(p.into()))
|
||||
});
|
||||
|
||||
v.name.map(|n| {
|
||||
root.insert(
|
||||
"Server.Name".to_owned(),
|
||||
ConfigString(n.into()),
|
||||
)
|
||||
});
|
||||
|
||||
v.owner.map(|o| {
|
||||
root.insert(
|
||||
"Server.Owner".to_owned(),
|
||||
ConfigString(o.into()),
|
||||
)
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Self {
|
||||
file,
|
||||
root: stored.clone(),
|
||||
root,
|
||||
stored,
|
||||
subscribers: Vec::default(),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,13 +2,12 @@
|
|||
//! This module contains all the code that deals with server configuration.
|
||||
//! It tries to implement a singleton actor, that will be fetchable globaly.
|
||||
|
||||
mod arg_fetcher;
|
||||
pub mod arg_parser;
|
||||
mod builder;
|
||||
mod config_manager;
|
||||
mod messages;
|
||||
mod types;
|
||||
|
||||
pub(crate) use arg_fetcher::get_args;
|
||||
pub(crate) use config_manager::ConfigManager;
|
||||
pub(crate) use messages::{
|
||||
ConfigManagerDataMessage, ConfigManagerDataResponse, ConfigManagerOutput,
|
||||
|
|
|
|||
Loading…
Reference in New Issue