diff --git a/journal/src/helpers.rs b/journal/src/helpers.rs index e202e2d..367079a 100644 --- a/journal/src/helpers.rs +++ b/journal/src/helpers.rs @@ -1,8 +1,6 @@ -use crate::types::{ - CustomUnitDose, CustomUnitIngestionDose, Estimation, IngestionDose, StandardIngestionDose, -}; +use crate::types::{CustomUnitIngestionDose, StandardIngestionDose}; -pub fn add_standard_deviation( +pub fn calculate_standard_deviation( expectation_x: f64, standard_deviation_x: f64, expectation_y: f64, @@ -24,39 +22,10 @@ pub fn add_standard_deviation( pub fn calulate_custom_unit_ingestion_dose( dose: &CustomUnitIngestionDose, - custom_unit_dose: &CustomUnitDose, -) -> IngestionDose { - let estimation = match (&dose.estimation, &custom_unit_dose.estimation) { - ( - &Estimation::StandardDeviation(dose_standard_deviation), - &Estimation::StandardDeviation(custom_unit_standard_deviation), - ) => { - let result = add_standard_deviation( - dose.dose, - dose_standard_deviation, - custom_unit_dose.dose, - custom_unit_standard_deviation, - ); - if let Some(result) = result { - Estimation::StandardDeviation(result) - } else { - Estimation::Estimate - } - } - (&Estimation::StandardDeviation(dose_standard_deviation), _) => { - Estimation::StandardDeviation(dose_standard_deviation) - } - (_, &Estimation::StandardDeviation(custom_unit_standard_deviation)) => { - Estimation::StandardDeviation(custom_unit_standard_deviation) - } - (Estimation::Precise, Estimation::Precise) => Estimation::Precise, - _ => Estimation::Estimate, - }; + custom_unit_dose: &CustomUnitIngestionDose, +) -> StandardIngestionDose { + let dose: StandardIngestionDose = dose.clone().into(); + let custom_unit_dose: StandardIngestionDose = custom_unit_dose.clone().into(); - IngestionDose::Standard(StandardIngestionDose { - dose: dose.dose * custom_unit_dose.dose, - unit: custom_unit_dose.original_unit.clone(), - contains_unknown: false, - estimation, - }) + custom_unit_dose * dose } diff --git a/journal/src/types.rs b/journal/src/types.rs index e684d25..6fa5547 100644 --- a/journal/src/types.rs +++ b/journal/src/types.rs @@ -1,7 +1,7 @@ use chrono::{DateTime, TimeZone, Utc}; use std::collections::HashMap; use std::fmt::{Debug, Display}; -use std::ops::Add; +use std::ops::{Add, Mul}; use std::str::FromStr; pub type AdministrationRoute = psychonaut_journal_types::AdministrationRoute; @@ -42,6 +42,23 @@ impl Add for Estimation { } } +impl Mul for Estimation { + type Output = Self; + + fn mul(self, rhs: Self) -> Self::Output { + match (self, rhs) { + (Estimation::StandardDeviation(x), Estimation::StandardDeviation(y)) => { + Estimation::StandardDeviation(x * y) + } + (Estimation::StandardDeviation(x), _) | (_, Estimation::StandardDeviation(x)) => { + Estimation::StandardDeviation(x) + } + (Estimation::Estimate, _) | (_, Estimation::Estimate) => Estimation::Estimate, + (Estimation::Precise, Estimation::Precise) => Estimation::Precise, + } + } +} + #[derive(Debug, Clone)] pub struct UnknownIngestionDose { pub unit: String, @@ -55,19 +72,6 @@ pub struct StandardIngestionDose { pub estimation: Estimation, } -impl Add for StandardIngestionDose { - type Output = Self; - - fn add(self, _: UnknownIngestionDose) -> Self::Output { - StandardIngestionDose { - dose: self.dose, - unit: self.unit, - contains_unknown: true, - estimation: self.estimation, - } - } -} - impl Add for StandardIngestionDose { type Output = Self; @@ -81,8 +85,41 @@ impl Add for StandardIngestionDose { } } -impl From for StandardIngestionDose { - fn from(value: CustomUnitDose) -> StandardIngestionDose { +impl Add for StandardIngestionDose { + type Output = Self; + + fn add(self, _rhs: UnknownIngestionDose) -> Self::Output { + StandardIngestionDose { + dose: self.dose, + unit: self.unit, + contains_unknown: true, + estimation: self.estimation, + } + } +} + +impl Mul for StandardIngestionDose { + type Output = Self; + + fn mul(self, rhs: Self) -> Self::Output { + StandardIngestionDose { + dose: self.dose * rhs.dose, + unit: self.unit, + contains_unknown: self.contains_unknown || rhs.contains_unknown, + estimation: { + let estimation = self.estimation + rhs.estimation; + if let Estimation::StandardDeviation(deviation) = estimation { + Estimation::StandardDeviation(deviation * rhs.dose) + } else { + estimation + } + }, + } + } +} + +impl From for StandardIngestionDose { + fn from(value: CustomUnitIngestionDose) -> StandardIngestionDose { StandardIngestionDose { dose: value.dose, unit: value.original_unit, @@ -96,6 +133,7 @@ impl From for StandardIngestionDose { pub struct CustomUnitIngestionDose { pub dose: f64, pub unit: String, + pub original_unit: String, pub estimation: Estimation, pub custom_unit_id: i64, } @@ -162,14 +200,6 @@ pub struct Experience { pub ingestions: Vec, } -#[derive(Debug, Clone)] -pub struct CustomUnitDose { - pub dose: f64, - pub unit: String, - pub original_unit: String, - pub estimation: Estimation, -} - #[derive(Debug, Clone)] pub struct CustomUnit { pub id: i64, @@ -177,7 +207,7 @@ pub struct CustomUnit { pub substance_name: String, pub administration_route: AdministrationRoute, - pub dose: CustomUnitDose, + pub dose: CustomUnitIngestionDose, pub creation_time: DateTime, pub is_archived: bool, @@ -229,10 +259,11 @@ impl Journal { substance_name: custom_unit.substance_name, administration_route: custom_unit.administration_route, - dose: CustomUnitDose { + dose: CustomUnitIngestionDose { dose: custom_unit.dose, unit: custom_unit.unit, original_unit: custom_unit.original_unit, + custom_unit_id: custom_unit.id, estimation: if custom_unit.is_estimate { if let Some(standard_deviation) = custom_unit.estimate_standard_deviation @@ -285,6 +316,7 @@ impl Journal { IngestionDose::CustomUnit(CustomUnitIngestionDose { dose, unit: custom_unit.dose.unit.clone(), + original_unit: custom_unit.dose.original_unit.clone(), estimation, custom_unit_id, }) diff --git a/journal_cli/src/formatting.rs b/journal_cli/src/formatting.rs index 1ca0c02..439b47d 100644 --- a/journal_cli/src/formatting.rs +++ b/journal_cli/src/formatting.rs @@ -1,7 +1,7 @@ use journal::{ helpers::calulate_custom_unit_ingestion_dose, types::{ - CustomUnit, CustomUnitDose, Estimation, Experience, Ingestion, IngestionDose, + CustomUnit, CustomUnitIngestionDose, Estimation, Experience, Ingestion, IngestionDose, StandardIngestionDose, }, }; @@ -12,7 +12,7 @@ pub fn format_experience_title(experience: &Experience) -> String { pub fn format_ingestion_dose( dose: &IngestionDose, - custom_unit_dose: Option<&CustomUnitDose>, + custom_unit_dose: Option<&CustomUnitIngestionDose>, ) -> String { match dose { IngestionDose::Unknown(dose) => format!("Unknown {}", dose.unit), @@ -37,7 +37,8 @@ pub fn format_ingestion_dose( let ingestion_dose = calulate_custom_unit_ingestion_dose(dose, custom_unit_dose); - let ingestion_dose = format_ingestion_dose(&ingestion_dose, None); + let ingestion_dose = + format_ingestion_dose(&IngestionDose::Standard(ingestion_dose), None); let dose_per_unit = format_ingestion_dose( &IngestionDose::Standard(StandardIngestionDose::from(custom_unit_dose.clone())),