aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGuillermo Ramos2025-03-09 16:07:47 +0100
committerGuillermo Ramos2025-03-14 11:52:04 +0100
commit5feb5cf771d473ff9f55be40169ca5db2bafd268 (patch)
treea77d32e59daae7a0e2f98919b85706b18debb090 /src
parent60f037e68466f2ba2137285cfa8e88782dcd905f (diff)
downloadhiccup-5feb5cf771d473ff9f55be40169ca5db2bafd268.tar.gz
Updates in front (RO)
Diffstat (limited to 'src')
-rw-r--r--src/bin/web.rs13
-rw-r--r--src/lib.rs48
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();
diff --git a/src/lib.rs b/src/lib.rs
index 423f607..1f4a977 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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 {