linted the code.

This commit is contained in:
didier amyot committed 2023-02-25 22:10:18 -05:00
1 parent 0c171171c2
commit f4170610b0
12 files changed
+83 -56

No files matched your search

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