From 3938b2032ddb7e4d06b566d2d8916cda612c06e2 Mon Sep 17 00:00:00 2001 From: Jolimaitre Matthieu Date: Fri, 12 Nov 2021 21:01:35 +0100 Subject: [PATCH] progress on overall structure --- Cargo.lock | 18 ++++++++++ Cargo.toml | 11 +++--- config.ron | 4 +++ database/conf | 4 +++ database/db | Bin 0 -> 524287 bytes database/snap.0000000000000060 | Bin 0 -> 69 bytes src/lib/config.rs | 54 ++++++++++++++++++++++++++++-- src/lib/database.rs | 15 --------- src/lib/db/mod.rs | 20 +++++++++++ src/lib/db/models.rs | 18 ++++++++++ src/lib/harsh.rs | 59 ++++++++++++++++++++++++++------- src/lib/http.rs | 20 ----------- src/lib/http/mod.rs | 45 +++++++++++++++++++++++++ src/lib/http/models.rs | 16 +++++++++ src/lib/http/routes.rs | 15 +++++++++ src/lib/log.rs | 2 +- src/lib/mod.rs | 21 +++++++++++- src/main.rs | 8 +++-- 18 files changed, 272 insertions(+), 58 deletions(-) create mode 100644 config.ron create mode 100644 database/conf create mode 100644 database/db create mode 100644 database/snap.0000000000000060 delete mode 100644 src/lib/database.rs create mode 100644 src/lib/db/mod.rs create mode 100644 src/lib/db/models.rs delete mode 100644 src/lib/http.rs create mode 100644 src/lib/http/mod.rs create mode 100644 src/lib/http/models.rs create mode 100644 src/lib/http/routes.rs diff --git a/Cargo.lock b/Cargo.lock index f51f5f8..ea0759e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -59,6 +59,12 @@ dependencies = [ "tower-service", ] +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + [[package]] name = "bitflags" version = "1.3.2" @@ -221,6 +227,7 @@ dependencies = [ "axum", "chrono", "colored", + "ron", "serde", "serde_json", "sled", @@ -527,6 +534,17 @@ dependencies = [ "bitflags", ] +[[package]] +name = "ron" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b861ecaade43ac97886a512b360d01d66be9f41f3c61088b42cedf92e03d678" +dependencies = [ + "base64", + "bitflags", + "serde", +] + [[package]] name = "ryu" version = "1.0.5" diff --git a/Cargo.toml b/Cargo.toml index bba9c1c..fd7bd0b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ description = "Harmony server application" [dependencies] # async engine -tokio = { version = "1.0", features = ["full"] } +tokio = { version = "1.13.0", features = ["full"] } # http client axum = "0.3.2" @@ -16,9 +16,12 @@ axum = "0.3.2" sled = "0.34.7" # serialization -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0.68" +serde = { version = "1.0.130", features = ["derive"] } +serde_json = "1.0.69" # useful for logging -chrono = "0.4" +chrono = "0.4.19" colored = "2.0.0" + +# serialization format of config files +ron = "0.7.0" diff --git a/config.ron b/config.ron new file mode 100644 index 0000000..f5d0ac3 --- /dev/null +++ b/config.ron @@ -0,0 +1,4 @@ +( + database_path: "./database", + port: 42069 +) \ No newline at end of file diff --git a/database/conf b/database/conf new file mode 100644 index 0000000..4154d7c --- /dev/null +++ b/database/conf @@ -0,0 +1,4 @@ +segment_size: 524288 +use_compression: false +version: 0.34 +vQÁ \ No newline at end of file diff --git a/database/db b/database/db new file mode 100644 index 0000000000000000000000000000000000000000..c4d313c7775b17c65ef6795ff695c1888ed4573d GIT binary patch literal 524287 zcmeIuu?fNe5CzbSVhA?k2)c-)1R=2sh(y6o(b^$&j0~WKjeA>c{8nLU_NqJNVbU zS92M>+H9iDcCxuW)6c#*o!7l2lDLod$1ID^w-AqUJ Self { - todo!() + pub fn get() -> Self { + match Self::try_from_file() { + Ok(config) => config, + Err(_) => { + let result = Configuration::default(); + Configuration::write_config(&result); + result + } + } + } + + fn try_from_file() -> Result { + let content = Self::try_read()?; + let config: Configuration = ron::from_str(&content)?; + Ok(config) + } + + fn try_read() -> Result { + for path in CONFIG_PATHS { + match read_to_string(path) { + Ok(serialized) => return Ok(serialized), + _ => (), + } + } + Err("unable to locate or read config file".to_string().into()) + } + + fn write_config(data: &Self) { + let serialized = ron::to_string(data).unwrap(); + write(CONFIG_PATHS[0], serialized); + } +} + +impl Default for Configuration { + fn default() -> Self { + Self { + database_path: "./database".to_string(), + port: 42069, // haha funny number + } } } diff --git a/src/lib/database.rs b/src/lib/database.rs deleted file mode 100644 index e80892e..0000000 --- a/src/lib/database.rs +++ /dev/null @@ -1,15 +0,0 @@ -use super::config::Configuration; - -/// -/// handle the database access -/// -pub struct DbManager { - // -} - -impl DbManager { - /// constructor - pub fn new(_config: &Configuration) -> Self { - todo!() - } -} diff --git a/src/lib/db/mod.rs b/src/lib/db/mod.rs new file mode 100644 index 0000000..6baa80c --- /dev/null +++ b/src/lib/db/mod.rs @@ -0,0 +1,20 @@ +pub mod models; + +use sled::Db; + +use super::{config::Configuration, harsh::Error}; + +/// +/// handle the database access +/// +pub struct DbManager { + handle: Db, +} + +impl DbManager { + /// constructor + pub fn new(config: Configuration) -> Result { + let handle = sled::open(config.database_path)?; + Ok(DbManager { handle }) + } +} diff --git a/src/lib/db/models.rs b/src/lib/db/models.rs new file mode 100644 index 0000000..2ab6f65 --- /dev/null +++ b/src/lib/db/models.rs @@ -0,0 +1,18 @@ +type Id = u64; + +pub struct User { + username: String, + password: String, + id: Id, +} + +pub struct Channel { + name: String, + id: Id, + messages: Vec, +} + +pub struct Message { + content: String, + id: Id, +} diff --git a/src/lib/harsh.rs b/src/lib/harsh.rs index 2f7dbb0..6c0e8fd 100644 --- a/src/lib/harsh.rs +++ b/src/lib/harsh.rs @@ -1,33 +1,68 @@ +use std::error; +use std::sync::{Arc, RwLock}; + use super::config::Configuration; -use super::database::DbManager; +use super::db::DbManager; use super::http::HttpManager; use super::log::Logger; /// /// main function /// -pub fn main() { - let configuration = Configuration::read(); +pub async fn main() { + let configuration = Configuration::get(); + let instance = Harsh::new(configuration); + instance.serve().await; } pub struct Harsh { - db_manager: DbManager, - logger: Logger, - http_manager: HttpManager, + pub shared_state: SharedState, + pub http_manager: HttpManager, } impl Harsh { pub fn new(configuration: Configuration) -> Self { - let db_manager = DbManager::new(&configuration); - let logger = Logger::new(&configuration); - let http_manager = HttpManager::new(); + let db_manager = + DbManager::new(configuration.clone()).expect("failed to open / create the database"); + let logger = Logger::new(configuration.clone()); + let shared_state = State::new_shared(db_manager, logger); + let http_manager = HttpManager::new(configuration.clone(), shared_state.clone()); Harsh { - logger, - db_manager, + shared_state, http_manager, } } - fn serve(&mut self) {} + pub async fn serve(self) { + self.http_manager.serve().await; + } } + +/// +/// shared state arround the app +/// +pub struct State { + pub db_manager: RwLock, + pub logger: RwLock, +} + +impl State { + pub fn new_shared(db_manager: DbManager, logger: Logger) -> SharedState { + let state = State { + db_manager: RwLock::new(db_manager), + logger: RwLock::new(logger), + }; + Arc::new(state) + } +} + +/// +/// safe pointer to the shared state +/// +pub type SharedState = Arc; + +/// +/// error type for now.. +/// +pub type Error = Box; diff --git a/src/lib/http.rs b/src/lib/http.rs deleted file mode 100644 index ebdca62..0000000 --- a/src/lib/http.rs +++ /dev/null @@ -1,20 +0,0 @@ -use super::config::Configuration; -use super::database::DbManager; - -/// -/// listen for incoming requests and handle both incoming and outgoing requests -/// -pub struct HttpManager { - // -} - -impl HttpManager { - pub fn new() -> Self { - HttpManager {} - } - - /// listen for and handle received requests - pub fn serve(_config: &Configuration, _db_manager: &mut DbManager) { - todo!() - } -} diff --git a/src/lib/http/mod.rs b/src/lib/http/mod.rs new file mode 100644 index 0000000..140a766 --- /dev/null +++ b/src/lib/http/mod.rs @@ -0,0 +1,45 @@ +/// +/// contains every route handlers +/// +mod routes; + +/// +/// contains every models used by the http server +/// +pub mod models; + +use axum::{AddExtensionLayer, Router}; + +use self::routes::setup_routes; + +use super::config::Configuration; +use super::harsh::SharedState; + +/// +/// listen for incoming requests and handle both incoming and outgoing requests +/// +pub struct HttpManager { + _shared_state: SharedState, + app: Router, +} + +impl HttpManager { + /// constructor + pub fn new(_config: Configuration, shared_state: SharedState) -> Self { + let app = setup_routes(Router::new()).layer(AddExtensionLayer::new(shared_state.clone())); + + HttpManager { + _shared_state: shared_state.clone(), + app, + } + } + + /// listen for and handle received requests + pub async fn serve(self) { + let address = "0.0.0.0:3000".parse().unwrap(); + axum::Server::bind(&address) + .serve(self.app.into_make_service()) + .await + .unwrap(); + } +} diff --git a/src/lib/http/models.rs b/src/lib/http/models.rs new file mode 100644 index 0000000..e979def --- /dev/null +++ b/src/lib/http/models.rs @@ -0,0 +1,16 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize)] +pub struct CreateUser { + name: String, + password: String, +} + +pub struct EditUser { + // +} + +pub struct DeleteUser { + name: String, + password: String, +} diff --git a/src/lib/http/routes.rs b/src/lib/http/routes.rs new file mode 100644 index 0000000..fe7886a --- /dev/null +++ b/src/lib/http/routes.rs @@ -0,0 +1,15 @@ +use axum::extract::{Extension, Json}; +use axum::routing::get; +use axum::Router; + +use crate::lib::harsh::SharedState; + +use super::models::*; + +pub fn setup_routes(app: Router) -> Router { + app.route("/user/create", get(create_user)) +} + +async fn create_user(Extension(state): Extension, Json(payload): Json) { + // +} diff --git a/src/lib/log.rs b/src/lib/log.rs index c889214..f6253e9 100644 --- a/src/lib/log.rs +++ b/src/lib/log.rs @@ -11,7 +11,7 @@ pub struct Logger { impl Logger { /// adapt the static instance according to parameters specified by the configuration - pub fn new(_config: &Configuration) -> Self { + pub fn new(_config: Configuration) -> Self { Logger {} } diff --git a/src/lib/mod.rs b/src/lib/mod.rs index 4091b14..40e9033 100644 --- a/src/lib/mod.rs +++ b/src/lib/mod.rs @@ -1,5 +1,24 @@ +/// +/// encapsulate the logic responsible for reading and parsing the server configuration +/// pub mod config; -pub mod database; + +/// +/// encapsulate the logic responsible for interacting with the database +/// +pub mod db; + +/// +/// main module, exposes the highest level structure holding the whole server runtime logic +/// pub mod harsh; + +/// +/// encapsulate the logic responsible for receiving and routing http requests +/// pub mod http; + +/// +/// encapsulate the logic responsible for logging events occuring while the server is running +/// pub mod log; diff --git a/src/main.rs b/src/main.rs index b17108b..6b3a094 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,10 @@ +/// +/// library module +/// pub mod lib; -pub fn main() { +#[tokio::main] +pub async fn main() { println!("Hello, harmony!"); - lib::harsh::main(); + lib::harsh::main().await; }