diff --git a/src/db/_securities.rs b/src/db/_securities.rs index 131f21a..6ecfbee 100644 --- a/src/db/_securities.rs +++ b/src/db/_securities.rs @@ -1,4 +1,4 @@ -use rusqlite::{Connection, params, Result, Row, ToSql, Transaction}; +use rusqlite::{params, Connection, Result, Row, ToSql, Transaction}; use serde::Serialize; use crate::db::_external_id::{Id, SecurityId}; @@ -106,7 +106,7 @@ pub fn list_securities(conn: &Connection) -> CustomResult> { #[cfg(test)] mod test_securities { - use rusqlite::{Connection, params}; + use rusqlite::{params, Connection}; use crate::db::_test_utils::*; use crate::db::users::User; diff --git a/src/db/_test_utils.rs b/src/db/_test_utils.rs index 8d910e6..debdbb9 100644 --- a/src/db/_test_utils.rs +++ b/src/db/_test_utils.rs @@ -1,4 +1,4 @@ -use rusqlite::{Transaction}; +use rusqlite::Transaction; use crate::db::_accounts::create_checking_account; use crate::db::_external_id::UserId; diff --git a/src/db/_users.rs b/src/db/_users.rs index 31fb4fa..1131f91 100644 --- a/src/db/_users.rs +++ b/src/db/_users.rs @@ -1,4 +1,4 @@ -use rusqlite::{Connection, params, Result, Row, Transaction}; +use rusqlite::{params, Connection, Result, Row, Transaction}; use serde::Serialize; use crate::db::_external_id::{Id, UserId}; diff --git a/src/db/mod.rs b/src/db/mod.rs index e01ce09..a83d3e8 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -11,7 +11,9 @@ pub mod external_id { } pub mod securities { - pub use super::_securities::{get_security_by_id, create_security, list_securities, Security, NewSecurity, SecurityType}; + pub use super::_securities::{ + create_security, get_security_by_id, list_securities, NewSecurity, Security, SecurityType, + }; } pub mod users { diff --git a/src/event_processor.rs b/src/event_processor.rs index 8e0be7d..1b92f65 100644 --- a/src/event_processor.rs +++ b/src/event_processor.rs @@ -5,7 +5,10 @@ use crate::db::users::create_user; use crate::events::{CreateNewSecurity, CreateNewUser, Event}; use crate::util::{CustomResult, Error}; -fn process_create_new_security_event(tx: &Transaction, event: CreateNewSecurity) -> CustomResult<()> { +fn process_create_new_security_event( + tx: &Transaction, + event: CreateNewSecurity, +) -> CustomResult<()> { let r = event.to_create_new_security().unwrap(); create_security(tx, &r)?; Ok(()) diff --git a/src/events.rs b/src/events.rs index 8aa6fcd..f3137e9 100644 --- a/src/events.rs +++ b/src/events.rs @@ -10,21 +10,19 @@ pub struct CreateNewSecurity { } impl CreateNewSecurity { - fn get_security_type(&self) -> Option{ + fn get_security_type(&self) -> Option { SecurityType::from_string(self.security_type.clone()) } pub fn to_create_new_security(&self) -> Option { - self.get_security_type() - .map(|security_type| - NewSecurity { - security_type, - symbol: self.symbol.clone(), - name: self.name.clone(), - }) + self.get_security_type().map(|security_type| NewSecurity { + security_type, + symbol: self.symbol.clone(), + name: self.name.clone(), + }) } - fn validate_event(&self) -> Result<(), String>{ - if SecurityType::from_string(self.security_type.clone()).is_none(){ + fn validate_event(&self) -> Result<(), String> { + if SecurityType::from_string(self.security_type.clone()).is_none() { Err(format!("Invalid SecurityType \"{}\".", self.security_type)) } else { Ok(()) @@ -45,10 +43,10 @@ pub enum Event { } impl Event { - pub fn validate_event(&self) -> Result<(), String>{ + pub fn validate_event(&self) -> Result<(), String> { match self { Event::CreateNewSecurity(event) => event.validate_event(), _ => Ok(()), } } -} \ No newline at end of file +} diff --git a/src/main.rs b/src/main.rs index b656ec2..b74fb81 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ use std::path::PathBuf; -use clap::{Arg, ArgAction, ArgMatches, Command, value_parser}; use clap::parser::ValuesRef; +use clap::{value_parser, Arg, ArgAction, ArgMatches, Command}; use log::{debug, error, info}; use rusqlite::Connection; use serde::Serialize; @@ -16,11 +16,11 @@ use crate::webui::web_ui_main; mod db; mod event_processor; +mod events; mod migration; mod services; mod util; mod webui; -mod events; #[derive(Debug, Serialize)] struct Output { @@ -296,7 +296,9 @@ fn process_wui_command_line( ) -> CustomResult<()> { debug!("Processing wui command line {:?}.", m); match m.subcommand() { - Some(("run", run_wui_match)) => process_run_wui_command_line(connFact, run_wui_match, logic), + Some(("run", run_wui_match)) => { + process_run_wui_command_line(connFact, run_wui_match, logic) + } _ => unreachable!(), } } @@ -313,7 +315,9 @@ fn process_command_line( Some(("securities", securities_match)) => { process_securities_command_line(&mut conn, securities_match, logic) } - Some(("events", events_match)) => process_events_command_line(&mut conn, events_match, logic), + Some(("events", events_match)) => { + process_events_command_line(&mut conn, events_match, logic) + } Some(("wui", wui_match)) => process_wui_command_line(connFact, wui_match, logic), _ => { println!("Received un parsable command. {:?}", m.subcommand()); diff --git a/src/services/_users.rs b/src/services/_users.rs index c53a3d5..452ab20 100644 --- a/src/services/_users.rs +++ b/src/services/_users.rs @@ -7,18 +7,24 @@ use crate::db::users::{list_users, User}; use crate::util::CustomResult; #[derive(Serialize, Debug)] -pub struct Page where T: Serialize { +pub struct Page +where + T: Serialize, +{ total_number_of_page: usize, current_page_number: usize, content: Vec, } -impl Page where T: Serialize{ - pub fn all_of(data: Vec) -> Page{ - Page{ +impl Page +where + T: Serialize, +{ + pub fn all_of(data: Vec) -> Page { + Page { total_number_of_page: 0, current_page_number: 10, - content: data + content: data, } } } @@ -26,12 +32,15 @@ impl Page where T: Serialize{ #[derive(Deserialize, Serialize, Debug)] pub struct UserDTO { name: String, - id: String, // todo: should be of type UserId + id: String, // todo: should be of type UserId } impl UserDTO { fn from_entity(user: &User) -> UserDTO { - return UserDTO { name: user.get_name(), id: user.id().to_string() } + return UserDTO { + name: user.get_name(), + id: user.id().to_string(), + }; } } @@ -45,8 +54,11 @@ impl UserService<'_> { } pub fn list_users(self) -> CustomResult> { - let users = list_users(self.conn)?.iter().map(UserDTO::from_entity).collect(); + let users = list_users(self.conn)? + .iter() + .map(UserDTO::from_entity) + .collect(); let ret = Page::all_of(users); - return Ok(ret) + return Ok(ret); } } diff --git a/src/util.rs b/src/util.rs index 924125e..951dd66 100644 --- a/src/util.rs +++ b/src/util.rs @@ -64,25 +64,25 @@ pub struct SQLiteConnectionFactory { impl SQLiteConnectionFactory { pub fn new(path: PathBuf) -> SQLiteConnectionFactory { SQLiteConnectionFactory { - creator: SQLiteConnectionCreator::Path(PathSQLiteConnectionCreator { path }) + creator: SQLiteConnectionCreator::Path(PathSQLiteConnectionCreator { path }), } } pub fn inMemory() -> SQLiteConnectionFactory { SQLiteConnectionFactory { - creator: SQLiteConnectionCreator::Ephemeral(EphemeralSQLiteConnectionCreator {}) + creator: SQLiteConnectionCreator::Ephemeral(EphemeralSQLiteConnectionCreator {}), } } pub fn connection(&self) -> CustomResult { - match & self.creator { + match &self.creator { SQLiteConnectionCreator::Path(c) => c.connection(), SQLiteConnectionCreator::Ephemeral(c) => c.connection(), } } pub fn readonly(&self) -> CustomResult { - match & self.creator { + match &self.creator { SQLiteConnectionCreator::Path(c) => c.readonly(), SQLiteConnectionCreator::Ephemeral(c) => c.readonly(), } diff --git a/src/webui/mod.rs b/src/webui/mod.rs index 141a752..25a7d53 100644 --- a/src/webui/mod.rs +++ b/src/webui/mod.rs @@ -4,15 +4,15 @@ use std::{env, path::PathBuf}; use actix_files; use actix_web::{ - App, dev::ServiceResponse, error, - FromRequest, - http::{header::ContentType, StatusCode}, HttpRequest, HttpResponse, HttpServer, middleware::{ErrorHandlerResponse, ErrorHandlers, Logger}, Responder, Result, web, + http::{header::ContentType, StatusCode}, + middleware::{ErrorHandlerResponse, ErrorHandlers, Logger}, + web, App, FromRequest, HttpRequest, HttpResponse, HttpServer, Responder, Result, }; use actix_web_lab::respond::Html; use async_channel; -use futures::{FutureExt, pin_mut, select}; +use futures::{pin_mut, select, FutureExt}; use minijinja; use minijinja_autoreload::AutoReloader; use rusqlite::Connection; @@ -83,9 +83,11 @@ fn create_auto_reloader(enable_template_autoreload: bool) -> AutoReloader { } #[tokio::main] -pub async fn web_ui_main(connFact: SQLiteConnectionFactory, - port: u16, - enable_template_autoreload: bool) -> CustomResult<()> { +pub async fn web_ui_main( + connFact: SQLiteConnectionFactory, + port: u16, + enable_template_autoreload: bool, +) -> CustomResult<()> { // The closure is invoked every time the environment is outdated to recreate it. let tmpl_reloader = create_auto_reloader(enable_template_autoreload); @@ -113,9 +115,9 @@ pub async fn web_ui_main(connFact: SQLiteConnectionFactory, .wrap(ErrorHandlers::new().handler(StatusCode::NOT_FOUND, not_found)) .wrap(Logger::default()) }) - .workers(2) - .bind(("0.0.0.0", port)) - .unwrap(); + .workers(2) + .bind(("0.0.0.0", port)) + .unwrap(); let t1 = server.run().fuse(); let t2 = event_processor_loop(connFact, event_receiver).fuse(); diff --git a/src/webui/views.rs b/src/webui/views.rs index 11e5937..afe4c19 100644 --- a/src/webui/views.rs +++ b/src/webui/views.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use actix_web::{error, HttpRequest, Responder, web}; +use actix_web::{error, web, HttpRequest, Responder}; use clap::builder::TypedValueParser; use log::info; use minijinja::context; @@ -23,8 +23,10 @@ pub async fn actions(tmpl_env: MiniJinjaRenderer) -> actix_web::Result) -> actix_web::Result { +pub async fn overview( + tmpl_env: MiniJinjaRenderer, + connFactory: web::Data, +) -> actix_web::Result { let conn = connFactory.readonly().unwrap(); // todo; to proper 500 let service_factory = ServiceFactory::new(&conn); let user_service = service_factory.get_user_service(); @@ -41,10 +43,11 @@ struct LoginPayload { password: String, } - #[actix_web::post("/login")] -pub async fn login(tmpl_env: MiniJinjaRenderer, - web::Json(form): web::Json) -> actix_web::Result { +pub async fn login( + tmpl_env: MiniJinjaRenderer, + web::Json(form): web::Json, +) -> actix_web::Result { let ctx = context! { name => form.username, }; @@ -55,7 +58,9 @@ pub async fn login(tmpl_env: MiniJinjaRenderer, pub async fn logout(tmpl_env: MiniJinjaRenderer) -> actix_web::Result { let ctx = context! {}; let res = tmpl_env.render("partials/index/form.html", ctx)?; - Ok(res.customize().insert_header(("Set-Cookie", "username=nobody"))) + Ok(res + .customize() + .insert_header(("Set-Cookie", "username=nobody"))) } #[actix_web::get("/partials/overview/submit_button")] @@ -86,7 +91,6 @@ pub async fn actions_partials( tmpl_env.render(template_location.as_str(), ctx) } - #[derive(Deserialize, Debug)] struct CreateEventPayload { event: Event, @@ -102,7 +106,7 @@ pub async fn push_event( ) -> actix_web::Result { let path_event_type = req.match_info().get("event_type").unwrap(); if path_event_type.to_string() != form.event_type { - return Err(error::ErrorBadRequest("Inconsistent event type.")) + return Err(error::ErrorBadRequest("Inconsistent event type.")); } let validation = form.event.validate_event(); if validation.is_err() { diff --git a/src/webui/worker.rs b/src/webui/worker.rs index b2e1e4b..8bacdb6 100644 --- a/src/webui/worker.rs +++ b/src/webui/worker.rs @@ -6,12 +6,14 @@ use tokio::time::sleep; use crate::event_processor::process_event; use crate::events::Event; -use crate::util::{CustomResult, SQLiteConnectionFactory}; use crate::util::Error::FuckingError; +use crate::util::{CustomResult, SQLiteConnectionFactory}; // todo, all the "?" and handle the exceptions for real -pub async fn event_processor_loop(conFact: SQLiteConnectionFactory, - r: async_channel::Receiver) -> CustomResult<()> { +pub async fn event_processor_loop( + conFact: SQLiteConnectionFactory, + r: async_channel::Receiver, +) -> CustomResult<()> { loop { let res = r.recv().await; let mut conn = conFact.connection()?;