diff options
author | Guillermo Ramos | 2025-03-09 16:07:47 +0100 |
---|---|---|
committer | Guillermo Ramos | 2025-03-14 11:52:04 +0100 |
commit | 5feb5cf771d473ff9f55be40169ca5db2bafd268 (patch) | |
tree | a77d32e59daae7a0e2f98919b85706b18debb090 /src | |
parent | 60f037e68466f2ba2137285cfa8e88782dcd905f (diff) | |
download | hiccup-5feb5cf771d473ff9f55be40169ca5db2bafd268.tar.gz |
Updates in front (RO)
Diffstat (limited to 'src')
-rw-r--r-- | src/bin/web.rs | 13 | ||||
-rw-r--r-- | src/lib.rs | 48 |
2 files changed, 35 insertions, 26 deletions
diff --git a/src/bin/web.rs b/src/bin/web.rs index 4d2938f..eba283c 100644 --- a/src/bin/web.rs +++ b/src/bin/web.rs @@ -4,8 +4,7 @@ use serde::Deserialize; use std::fs; use axum::{ response::{Html, Json}, - extract::Query, - routing::get, + routing::{get, post}, Router, }; @@ -40,11 +39,13 @@ struct SimSpecs { principal: f64, i1: f64, years: u32, + updates: SimUpdates } -async fn api_simulate_get<'a>(Query(specs): Query<SimSpecs>) -> Json<hiccup::Simulation<'a>> { - let mut sim = Simulation::new(specs. principal, specs.i1, specs.years); - let updates: SimUpdates = SimUpdates::default(); +async fn api_simulate_post(Json(specs): Json<SimSpecs>) -> Json<hiccup::Simulation> { + let mut sim = Simulation::new(specs.principal, specs.i1, specs.years); + let updates: SimUpdates = specs.updates; + // let updates: SimUpdates = SimUpdates::default(); sim.run(updates); Json(sim) } @@ -55,7 +56,7 @@ async fn main() { let app = Router::new() .route("/", get(root_get)) .route("/main.js", get(main_get)) - .route("/api/simulate", get(api_simulate_get)); + .route("/api/simulate", post(api_simulate_post)); // run our app with hyper, listening globally on port 3000 let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); @@ -2,6 +2,7 @@ use std::collections::HashMap; use std::fmt; use std::ops::AddAssign; +use serde::Deserialize; use serde::Serialize; #[derive(Clone, Copy, Serialize)] @@ -25,16 +26,16 @@ impl AddAssign for Capital { } #[derive(Serialize)] -pub struct Simulation<'a> { +pub struct Simulation { st: SimState, - updates: SimUpdates<'a>, + updates: SimUpdates, history: Vec<Quota>, topay: Capital, payed: Capital, payed_amortized: f64, } -impl<'a> Simulation<'a> { +impl Simulation { pub fn new(principal: f64, i1: f64, years: u32) -> Self { let pending_quotas = years * 12; let i12 = i1 / 12.0; @@ -66,7 +67,7 @@ impl<'a> Simulation<'a> { } } - pub fn run(&mut self, updates: SimUpdates<'a>) { + pub fn run(&mut self, updates: SimUpdates) { self.updates = updates; let mut st = self.st.clone(); while st.pending_quotas > 0 && st.principal > 0. { @@ -209,25 +210,32 @@ impl fmt::Display for Quota { } } -#[derive(Debug, Default, Serialize)] -pub struct SimUpdates<'a> { - periodically: Vec<(u32, Vec<&'a SimUpdate>)>, - by_month: HashMap<u32, Vec<&'a SimUpdate>>, +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct PeriodicUpdate { + period: u32, + from: Option<u32>, + to: Option<u32>, + update: SimUpdate, +} + +#[derive(Debug, Default, Serialize, Deserialize)] +pub struct SimUpdates { + periodically: Vec<PeriodicUpdate>, + by_month: HashMap<u32, Vec<SimUpdate>>, } -impl<'a> SimUpdates<'a> { - fn get(&self, month: u32) -> Vec<&'a SimUpdate> { +impl SimUpdates { + fn get(&self, month: u32) -> Vec<SimUpdate> { let SimUpdates { periodically, by_month, } = self; let mut ret = vec![]; - for (m, updates) in periodically.iter() { - if month % m == 0 { - for update in updates.iter() { - ret.push(*update); - } + for PeriodicUpdate{period, from, to, update} in periodically.iter() { + let base = from.unwrap_or(0); + if month % period == base && base <= month && to.unwrap_or(month+1) > month { + ret.push(*update); } } if let Some(updates) = by_month.get(&month) { @@ -239,7 +247,7 @@ impl<'a> SimUpdates<'a> { ret } - pub fn and(mut self, other: SimUpdates<'a>) -> Self { + pub fn and(mut self, other: SimUpdates) -> Self { for p in other.periodically.iter() { self.periodically.push(p.clone()); } @@ -250,7 +258,7 @@ impl<'a> SimUpdates<'a> { } } -#[derive(Clone, Debug, Serialize)] +#[derive(Clone, Copy, Debug, Serialize, Deserialize)] pub enum SimUpdate { Amortize(f64), } @@ -269,18 +277,18 @@ impl fmt::Display for SimUpdate { impl SimUpdate { pub fn every(&self, months: u32) -> SimUpdates { let mut updates = SimUpdates::default(); - updates.periodically.push((months, vec![self])); + updates.periodically.push(PeriodicUpdate{period: months, from: None, to: None, update: *self}); updates } pub fn at(&self, month: u32) -> SimUpdates { let mut updates = SimUpdates::default(); - updates.by_month.insert(month, vec![self]); + updates.by_month.insert(month, vec![*self]); updates } } -fn flatten_amortizations(updates: Vec<&SimUpdate>) -> Vec<SimUpdate> { +fn flatten_amortizations(updates: Vec<SimUpdate>) -> Vec<SimUpdate> { let mut amortized = 0.; let mut result = vec![]; for update in updates { |