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 { | 
