updated config manager api to use optionals. This leads to pre-configuration and easier readability and understanding.

This commit is contained in:
michael-bailey 2022-09-14 08:45:49 +01:00
parent ccbc680c0e
commit 5719bf98dd
6 changed files with 58 additions and 81 deletions

View File

@ -17,10 +17,7 @@ use crate::{
ConfigManagerDataMessage, ConfigManagerDataResponse,
ConfigManagerOutput,
},
types::{
ConfigError,
ConfigValue::{Dict, Number, String as ConfigString},
},
types::ConfigValue::{Dict, Number, String as ConfigString},
ConfigValue,
},
prelude::messages::ObservableMessage,
@ -54,50 +51,46 @@ impl ConfigManager {
// instance methods
impl ConfigManager {
pub fn get_value(&self, key: String) -> Result<ConfigValue, ConfigError> {
use ConfigError::{NoKey, NoValue};
pub fn get_value(&self, key: String) -> Option<ConfigValue> {
if let Dict(dict) = &self.root {
let opt_value = dict.get(&key);
return if let Some(value) = opt_value {
Ok(value.clone())
} else {
Err(NoValue)
};
dict.get(&key).cloned()
} else {
None
}
Err(NoKey)
}
pub fn set_value(
&mut self,
key: String,
value: ConfigValue,
) -> Result<ConfigValue, ConfigError> {
use ConfigError::IncompatableValue;
if let (Dict(stored), Dict(root)) = (&mut self.stored, &mut self.root) {
stored.insert(key.clone(), value.clone());
root.insert(key.clone(), value.clone());
Ok(value)
} else {
Err(IncompatableValue)
}
value: Option<ConfigValue>,
) -> Option<ConfigValue> {
value.and_then(|value| {
if let (Dict(stored), Dict(root)) =
(&mut self.stored, &mut self.root)
{
stored.insert(key.clone(), value.clone());
root.insert(key.clone(), value.clone());
Some(value)
} else {
None
}
})
}
// this doesn't work for now
pub fn soft_set_value(
&mut self,
key: String,
value: ConfigValue,
) -> Result<ConfigValue, ConfigError> {
use ConfigError::IncompatableValue;
if let Dict(root) = &mut self.root {
root.insert(key, value.clone());
Ok(value)
} else {
Err(IncompatableValue)
}
value: Option<ConfigValue>,
) -> Option<ConfigValue> {
value.and_then(|value| {
if let Dict(root) = &mut self.root {
root.insert(key, value.clone());
Some(value)
} else {
None
}
})
}
}
@ -111,7 +104,7 @@ impl Actor for ConfigManager {
}
impl Handler<ConfigManagerDataMessage> for ConfigManager {
type Result = Result<ConfigManagerDataResponse, ConfigError>;
type Result = ConfigManagerDataResponse;
fn handle(
&mut self,
@ -122,13 +115,13 @@ impl Handler<ConfigManagerDataMessage> for ConfigManager {
match msg {
ConfigManagerDataMessage::GetValue(val) => {
Ok(GotValue(self.get_value(val)?))
GotValue(self.get_value(val))
}
ConfigManagerDataMessage::SetValue(key, value) => {
Ok(SetValue(key.clone(), self.set_value(key, value)?))
SetValue(key.clone(), self.set_value(key, value))
}
ConfigManagerDataMessage::SoftSetValue(key, value) => {
Ok(SoftSetValue(key.clone(), self.soft_set_value(key, value)?))
SoftSetValue(key.clone(), self.soft_set_value(key, value))
}
}
}

View File

@ -1,4 +1,3 @@
use super::types::ConfigError;
use crate::config_manager::types::ConfigValue;
use actix::{Message, MessageResponse};
@ -9,16 +8,16 @@ pub enum ConfigManagerOutput {
}
#[derive(Message, Debug)]
#[rtype(result = "Result<ConfigManagerDataResponse, ConfigError>")]
#[rtype(result = "ConfigManagerDataResponse")]
pub enum ConfigManagerDataMessage {
GetValue(String),
SetValue(String, ConfigValue),
SoftSetValue(String, ConfigValue),
SetValue(String, Option<ConfigValue>),
SoftSetValue(String, Option<ConfigValue>),
}
#[derive(MessageResponse, Debug)]
pub enum ConfigManagerDataResponse {
GotValue(ConfigValue),
SetValue(String, ConfigValue),
SoftSetValue(String, ConfigValue),
GotValue(Option<ConfigValue>),
SetValue(String, Option<ConfigValue>),
SoftSetValue(String, Option<ConfigValue>),
}

View File

@ -10,6 +10,6 @@ mod types;
pub(crate) use config_manager::ConfigManager;
pub(crate) use messages::{
ConfigManagerDataMessage, ConfigManagerDataResponse, ConfigManagerOutput,
ConfigManagerDataMessage, ConfigManagerDataResponse,
};
pub(crate) use types::ConfigValue;

View File

@ -1,14 +1,6 @@
use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, HashMap};
use std::ops::Index;
use toml::value::Value;
use std::collections::BTreeMap;
#[derive(Debug)]
pub enum ConfigError {
NoKey,
IncompatableValue,
NoValue,
}
use toml::value::Value;
/// # ConfigValue
/// Each value type that can be used within a config file.

View File

@ -2,31 +2,24 @@ use super::*;
use actix::{Actor, Addr};
pub struct ServerBuilder {
pub(super) name: Option<String>,
pub(super) port: Option<u16>,
pub(super) owner: Option<String>,
pub(super) name: String,
pub(super) owner: String,
}
impl<'rhai> ServerBuilder {
pub(super) fn new() -> Self {
Self {
name: None,
port: None,
owner: None,
name: "<UNKNOWN>".into(),
owner: "<UNKNOWN>".into(),
}
}
pub fn port(mut self, port: Option<u16>) -> Self {
self.port = port;
self
}
pub fn name(mut self, name: Option<String>) -> Self {
pub fn name(mut self, name: String) -> Self {
self.name = name;
self
}
pub fn owner(mut self, owner: Option<String>) -> Self {
pub fn owner(mut self, owner: String) -> Self {
self.owner = owner;
self
}

View File

@ -26,8 +26,8 @@ use foundation::ClientDetails;
/// This struct is the main actor of the server.
/// all other actors are ran through here.
pub struct Server {
name: Option<String>,
owner: Option<String>,
name: String,
owner: String,
network_manager: Option<Addr<NetworkManager>>,
client_manager: Option<Addr<ClientManager>>,
@ -60,8 +60,8 @@ impl Server {
let fut = wrap_future(
sender.send(SendData(
serde_json::to_string(&GotInfo {
server_name: self.name.as_ref().unwrap().clone(),
server_owner: self.owner.as_ref().unwrap().clone(),
server_name: self.name.clone(),
server_owner: self.owner.clone(),
})
.expect("Failed to serialise"),
)),
@ -106,7 +106,7 @@ impl Actor for Server {
);
if let GotValue(ConfigValue::String(name)) = out {
actor.name = Some(name);
actor.name = name;
}
});
@ -120,7 +120,7 @@ impl Actor for Server {
);
if let GotValue(ConfigValue::String(owner)) = out {
actor.owner = Some(owner);
actor.owner = owner;
}
});
@ -140,10 +140,10 @@ impl Handler<ServerDataMessage> for Server {
println!("data message");
match msg {
ServerDataMessage::Name => {
ServerDataResponse::Name(self.name.as_ref().unwrap().clone())
ServerDataResponse::Name(self.name.clone())
}
ServerDataMessage::Owner => {
ServerDataResponse::Owner(self.owner.as_ref().unwrap().clone())
ServerDataResponse::Owner(self.owner.clone())
}
ServerDataMessage::ClientManager => {
ServerDataResponse::ClientManager(self.client_manager.clone())
@ -187,10 +187,10 @@ impl Handler<ClientManagerOutput> for Server {
}
impl From<ServerBuilder> for Server {
fn from(_builder: ServerBuilder) -> Self {
fn from(builder: ServerBuilder) -> Self {
Server {
name: None,
owner: None,
name: builder.name,
owner: builder.owner,
network_manager: None,
client_manager: None,