diff --git a/.gitignore b/.gitignore index ea8c4bf..b3982b7 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +config.private.yaml \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 691ded5..13e5f8b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,3 +3,21 @@ [[package]] name = "comunic_server" version = "0.1.0" +dependencies = [ + "yaml-rust", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a" + +[[package]] +name = "yaml-rust" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65923dd1784f44da1d2c3dbbc5e822045628c590ba72123e1c73d3c230c4434d" +dependencies = [ + "linked-hash-map", +] diff --git a/Cargo.toml b/Cargo.toml index a2c052b..86e0877 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,3 +7,4 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +yaml-rust = "0.4.3" \ No newline at end of file diff --git a/config.yaml b/config.yaml new file mode 100644 index 0000000..59b76eb --- /dev/null +++ b/config.yaml @@ -0,0 +1,29 @@ +# Sample server configuration +# +# Copy and paste this file as +# config.private.yaml to edit it safely +# +# @author Pierre HUBERT + +# Server listening information +server-address: 0.0.0.0 +server-port: 3000 + +# Server proxy (none = no proxy) +# This value is used to trust upstream +# IP addresses +proxy: none + +# If set to true Access-Control-Allow-Origin will be set for https +force-https: false + +# User data storage +storage-url: https://devweb.local/comunic/current/user_data/ +storage-path: /home/pierre/Documents/projets_web/comunic/current/user_data/ + +# Database configuration +database: + host: localhost + name: comunic + username: pierre + password: pierre \ No newline at end of file diff --git a/src/data/config.rs b/src/data/config.rs new file mode 100644 index 0000000..a3d1047 --- /dev/null +++ b/src/data/config.rs @@ -0,0 +1,97 @@ +use std::error::Error; + +use yaml_rust::{Yaml, YamlLoader}; + +/// Server configuration +/// +/// @author Pierre Hubert +#[derive(Debug)] +pub struct DatabaseConfig { + pub host: String, + pub name: String, + pub username: String, + pub password: String, +} + +#[derive(Debug)] +pub struct Config { + pub port: i32, + pub listen_address: String, + pub storage_url: String, + pub storage_path: String, + pub database: DatabaseConfig, + pub proxy: Option, + pub force_https: bool, +} + +/// Globally available configuration +static mut CONF: Option = None; + +impl Config { + fn yaml_i32(parsed: &Yaml, name: &str) -> i32 { + parsed[name].as_i64().expect(format!("{} is missing (int)", name).as_str()) as i32 + } + + fn yaml_str(parsed: &Yaml, name: &str) -> String { + parsed[name].as_str().expect(format!("{} is missing (str)", name).as_str()).to_string() + } + + fn yaml_bool(parsed: &Yaml, name: &str) -> bool { + parsed[name].as_bool().expect(format!("{} is missing (bool)", name).as_str()) + } + + /// Load the configuration from a given path + pub fn load(path: &str) -> Result<(), Box> { + + // Read & parse configuration + let conf_str = std::fs::read_to_string(path)?; + let parsed = YamlLoader::load_from_str(&conf_str)?; + + if parsed.len() != 1 { + panic!("parsed.len() != 1"); + } + let parsed = &parsed[0]; + + // Read configuration + let parsed_db = &parsed["database"]; + let database_conf = DatabaseConfig { + host: Config::yaml_str(parsed_db, "host"), + name: Config::yaml_str(parsed_db, "name"), + username: Config::yaml_str(parsed_db, "username"), + password: Config::yaml_str(parsed_db, "password"), + }; + + let proxy = Config::yaml_str(parsed, "proxy"); + + let conf = Config { + port: Config::yaml_i32(parsed, "server-port") as i32, + listen_address: Config::yaml_str(parsed, "server-address"), + + storage_url: Config::yaml_str(parsed, "storage-url"), + storage_path: Config::yaml_str(parsed, "storage-path"), + + database: database_conf, + + proxy: match proxy.as_ref() { + "none" => None, + s => Some(s.to_string()) + }, + + force_https: Config::yaml_bool(parsed, "force-https"), + }; + + // Save new configuration in memory + unsafe { + CONF = Some(conf); + } + + Ok(()) + } +} + +/// Get an instance of the configuration +pub fn conf() -> &'static Config { + unsafe { + return &CONF.as_ref().unwrap(); + } +} \ No newline at end of file diff --git a/src/data/mod.rs b/src/data/mod.rs new file mode 100644 index 0000000..a105933 --- /dev/null +++ b/src/data/mod.rs @@ -0,0 +1 @@ +pub mod config; \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..12e35bb --- /dev/null +++ b/src/lib.rs @@ -0,0 +1 @@ +pub mod data; \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index e7a11a9..b05da05 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,11 @@ +use comunic_server::data::config::{conf, Config}; + fn main() { + + // Load configuration + Config::load("config.yaml").expect("Could not load configuration!"); + + println!("{:#?}", conf()); + println!("Hello, world!"); }