This commit is contained in:
chaos 2024-11-27 20:49:53 +00:00
parent 5e4a4cc54f
commit f711240faa
5 changed files with 56 additions and 84 deletions

View file

@ -1,102 +1,72 @@
use std::{ use std::collections::HashMap;
collections::HashMap,
ops::{Add, Mul},
};
use crate::types::{Dose, HydrationIngestion, IngestionKind, Nutrients, SubstanceIngestion}; use crate::types::{
AdministrationRoute, Dose, HydrationIngestion, IngestionKind, Nutrients, SubstanceIngestion,
SustenanceIngestion,
};
#[derive(Debug, Default, PartialEq)] #[derive(Debug, Default, PartialEq)]
#[derive(serde::Serialize, serde::Deserialize)] #[derive(serde::Serialize, serde::Deserialize)]
pub struct CalculatedValues { pub struct CalculatedValues {
pub doses: HashMap<String, Dose>, pub substances: HashMap<String, SubstanceIngestion>,
pub nutrients: Nutrients, pub nutrients: Nutrients,
pub hydration: HydrationIngestion, pub hydration: HydrationIngestion,
} }
impl Add<CalculatedValues> for CalculatedValues { pub fn calculate_sustenance_ingestion_amounts(sustenance: &mut SustenanceIngestion) {
type Output = CalculatedValues; let includes = &mut sustenance.sustenance.as_mut().unwrap().includes;
fn add(self, rhs: CalculatedValues) -> Self::Output { for include in includes.iter_mut() {
let mut doses = self.doses.clone(); match include {
let mut nutrients = self.nutrients.clone(); IngestionKind::Substance(ingestion) => {
let mut hydration = self.hydration.clone(); ingestion.dose = Dose::new_precise(sustenance.amount) * ingestion.dose.clone();
for (substance_id, substance_dose) in rhs.doses.iter() {
let dose = self
.doses
.get(substance_id)
.cloned()
.or(Some(Dose::new_precise(0.0)))
.unwrap();
doses.insert(substance_id.clone(), dose + substance_dose.clone());
} }
IngestionKind::Sustenance(ingestion) => {
ingestion.amount *= sustenance.amount;
nutrients.kcal += rhs.nutrients.kcal; calculate_sustenance_ingestion_amounts(ingestion)
hydration.amount_ml += rhs.hydration.amount_ml; }
IngestionKind::Hydration(hydration) => {
CalculatedValues { hydration.amount_ml *= sustenance.amount
doses, }
nutrients, _ => {}
hydration,
} }
} }
} }
impl Mul<f64> for CalculatedValues { pub fn calculate_sustenance_contents(root: SustenanceIngestion) -> CalculatedValues {
type Output = CalculatedValues; let mut values = CalculatedValues::default();
fn mul(self, rhs: f64) -> Self::Output {
let mut doses = self.doses.clone();
let mut nutrients = self.nutrients.clone();
let mut hydration = self.hydration.clone();
for (_substance_id, substance_dose) in doses.iter_mut() {
*substance_dose = substance_dose.clone() * Dose::new_precise(rhs);
}
nutrients.kcal = (rhs * nutrients.kcal as f64).round() as u64;
hydration.amount_ml *= rhs;
CalculatedValues {
doses,
nutrients,
hydration,
}
}
}
impl CalculatedValues {
fn new() -> Self {
Self {
..Default::default()
}
}
}
pub fn calculate_ingestion_kind(kind: IngestionKind) -> CalculatedValues {
let mut values = CalculatedValues::new();
let mut ingestions: Vec<IngestionKind> = Vec::new(); let mut ingestions: Vec<IngestionKind> = Vec::new();
ingestions.push(kind); ingestions.push(IngestionKind::Sustenance(root));
while !ingestions.is_empty() { while !ingestions.is_empty() {
let current_ingestions = ingestions.clone(); let current_ingestions = ingestions.clone();
for kind in current_ingestions { for ingestion in current_ingestions {
match kind { match ingestion {
IngestionKind::Unknown => {} IngestionKind::Unknown => {}
IngestionKind::Substance(substance) => { IngestionKind::Substance(substance) => {
let dose = values let substance_ingestion = values
.doses .substances
.get(&substance.id) .get(&substance.id)
.cloned() .cloned()
.or(Some(Dose::new_precise(0.0))) .unwrap_or(SubstanceIngestion {
.unwrap(); id: substance.id.clone(),
substance: None,
dose: Dose::new_precise(0.0),
custom_unit_id: None,
roa: AdministrationRoute::Oral,
stomach_fullness: None,
});
values values.substances.insert(
.doses substance.id.clone(),
.insert(substance.id.clone(), dose + substance.dose.clone()); SubstanceIngestion {
dose: substance_ingestion.dose.clone() + substance.dose,
..substance_ingestion
},
);
} }
IngestionKind::Sustenance(sustenance) => { IngestionKind::Sustenance(sustenance) => {
let amount = sustenance.amount; let amount = sustenance.amount;

View file

@ -4,8 +4,7 @@ use chrono::Utc;
use rand::Rng; use rand::Rng;
use crate::types::{ use crate::types::{
CustomUnit, Dose, Ingestion, IngestionKind, Session, Substance, SubstanceIngestion, Sustenance, CustomUnit, Ingestion, IngestionKind, Session, Substance, SubstanceIngestion, Sustenance, Unit,
SustenanceIngestion, Unit,
}; };
use super::{Journal, JournalIntegrityChecks, JournalTrait, JournalType}; use super::{Journal, JournalIntegrityChecks, JournalTrait, JournalType};

View file

@ -1,4 +1,4 @@
use super::{from_unix_millis, AdministrationRoute, Dose}; use super::{AdministrationRoute, Dose};
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
#[derive(Default, PartialEq, Debug, Clone)] #[derive(Default, PartialEq, Debug, Clone)]

View file

@ -3,7 +3,7 @@ use std::{collections::HashMap, fs::File};
use journal::{ use journal::{
journal::JournalType, journal::JournalType,
types::{ types::{
Consumer, CustomUnit, Dose, Ingestion, IngestionKind, Session, Substance, Consumer, Dose, Ingestion, IngestionKind, Session, Substance,
SubstanceIngestion, SubstanceIngestion,
}, },
}; };

View file

@ -1,4 +1,5 @@
use journal::{ use journal::{
calculate::calculate_sustenance_ingestion_amounts,
journal::JournalType, journal::JournalType,
types::{ types::{
format_dose, Consumer, Ingestion, IngestionKind, Session, SubstanceIngestion, format_dose, Consumer, Ingestion, IngestionKind, Session, SubstanceIngestion,
@ -57,17 +58,21 @@ pub fn print_ingestion(journal: &JournalType, ingestion: &Ingestion, depth: u64)
match &ingestion.kind { match &ingestion.kind {
IngestionKind::Unknown => {} IngestionKind::Unknown => {}
IngestionKind::Substance(substance) => { IngestionKind::Substance(substance) => {
print_substance_ingestion(journal, ingestion, &substance); print_substance_ingestion(journal, ingestion, substance);
} }
IngestionKind::Sustenance(sustenance) => { IngestionKind::Sustenance(sustenance) => {
print_sustenance_ingestion(journal, ingestion, sustenance); let mut sustenance = sustenance.clone();
let sustenance = sustenance.sustenance.as_ref().unwrap(); calculate_sustenance_ingestion_amounts(&mut sustenance);
for include in &sustenance.includes { print_sustenance_ingestion(journal, ingestion, &sustenance);
let includes = sustenance.sustenance.unwrap().includes;
for include in includes {
print_ingestion( print_ingestion(
journal, journal,
&Ingestion { &Ingestion {
kind: include.clone(), kind: include,
..ingestion.clone() ..ingestion.clone()
}, },
depth + 1, depth + 1,
@ -105,8 +110,6 @@ pub fn print_ingestion_log(
.resolve_ingestion_kind(ingestion.kind.clone()) .resolve_ingestion_kind(ingestion.kind.clone())
.unwrap(); .unwrap();
//let calculated_values = calculate_ingestion_kinds(ingestion_kinds);
print_ingestion(journal, ingestion, 0) print_ingestion(journal, ingestion, 0)
} }
} }