diff --git a/kifu/core/src/api.rs b/kifu/core/src/api.rs index 7e4e0d6..810d3bd 100644 --- a/kifu/core/src/api.rs +++ b/kifu/core/src/api.rs @@ -1,6 +1,7 @@ use crate::{ types::{AppState, GameState, Player, Rank}, ui::{new_game, playing_field, NewGameView, PlayingFieldView}, + Config, }; use serde::{Deserialize, Serialize}; use std::sync::{Arc, RwLock}; @@ -64,14 +65,22 @@ pub enum CoreResponse { #[derive(Clone, Debug)] pub struct CoreApp { + config: Config, state: Arc>, } impl CoreApp { pub fn new() -> Self { + /* Candidate for dependency injection from the UI */ + let user_home = std::env::var("HOME").expect("the user's home directory isn't set"); + let mut config_path = std::path::PathBuf::from(user_home); + config_path.push(".config"); + config_path.push("kifu"); + + let config = Config::new(config_path); let state = Arc::new(RwLock::new(AppState::new())); - Self { state } + Self { config, state } } pub async fn dispatch(&self, request: CoreRequest) -> CoreResponse { diff --git a/kifu/core/src/config.rs b/kifu/core/src/config.rs new file mode 100644 index 0000000..401b7ed --- /dev/null +++ b/kifu/core/src/config.rs @@ -0,0 +1,91 @@ +use crate::types::Player; +use std::{collections::HashMap, path::PathBuf}; + +/* +pub trait ConfigOption { + type Value; +} + +pub struct DatabasePath(PathBuf); + +impl ConfigOption for DatabasePath { + type Value = PathBuf; +} + +impl ConfigOption for Player { + type Value = Player; +} + +pub trait Config { + // fn set_option(option: ConfigOption); + fn get_option(name: Name) -> C +} +*/ + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +enum OptionNames { + DatabasePath, + Me, +} + +#[derive(Clone, Debug)] +pub enum ConfigOption { + DatabasePath(DatabasePath), + Me(Me), +} + +#[derive(Clone, Debug)] +pub struct Config { + config_path: PathBuf, + values: HashMap, +} + +impl Config { + pub fn new(config_path: PathBuf) -> Self { + Self { + config_path, + values: HashMap::new(), + } + } + + fn set(&mut self, val: ConfigOption) { + let _ = match val { + ConfigOption::DatabasePath(_) => self.values.insert(OptionNames::DatabasePath, val), + ConfigOption::Me(_) => self.values.insert(OptionNames::Me, val), + }; + } + + fn get<'a, T>(&'a self) -> T + where + T: From<&'a Self>, + { + self.into() + } +} + +#[derive(Clone, Debug)] +pub struct DatabasePath(PathBuf); + +impl From<&Config> for DatabasePath { + fn from(config: &Config) -> Self { + match config.values.get(&OptionNames::DatabasePath) { + Some(ConfigOption::DatabasePath(path)) => path.clone(), + _ => DatabasePath(config.config_path.clone()), + } + } +} + +#[derive(Clone, Debug)] +pub struct Me(Player); + +impl From<&Config> for Option { + fn from(config: &Config) -> Self { + config + .values + .get(&OptionNames::Me) + .and_then(|val| match val { + ConfigOption::Me(me) => Some(me.clone()), + _ => None, + }) + } +} diff --git a/kifu/core/src/lib.rs b/kifu/core/src/lib.rs index fe0d321..b5b56da 100644 --- a/kifu/core/src/lib.rs +++ b/kifu/core/src/lib.rs @@ -9,3 +9,6 @@ pub mod ui; mod board; pub use board::*; + +mod config; +pub use config::*; diff --git a/kifu/core/src/types.rs b/kifu/core/src/types.rs index 3249ea4..a819c4c 100644 --- a/kifu/core/src/types.rs +++ b/kifu/core/src/types.rs @@ -91,7 +91,7 @@ impl From for String { } } -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct Player { pub name: String, pub rank: Option,