From 93105359f998e78895858d638fed765fe92de637 Mon Sep 17 00:00:00 2001 From: chaos Date: Sun, 24 Nov 2024 14:26:48 +0000 Subject: [PATCH] update --- Cargo.lock | 80 +++++++++++++++++++++++++++++ journal/Cargo.toml | 1 + journal/src/journal.rs | 7 +-- journal/src/journal/json_journal.rs | 24 +++++---- journal/src/types/ingestion.rs | 78 +++++++++++++++++----------- journal/src/types/mod.rs | 2 +- journal_cli/src/display.rs | 29 ++++------- journal_cli/src/formatting.rs | 18 +++---- 8 files changed, 168 insertions(+), 71 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b507c2a..21d3e35 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -229,6 +229,18 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" +[[package]] +name = "fraction" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f158e3ff0a1b334408dc9fb811cd99b446986f4d8b741bb08f9df1604085ae7" +dependencies = [ + "lazy_static", + "num", + "serde", + "serde_derive", +] + [[package]] name = "getrandom" version = "0.2.15" @@ -303,6 +315,7 @@ name = "journal" version = "0.1.0" dependencies = [ "chrono", + "fraction", "psychonaut_journal_types", "rand", "serde", @@ -367,6 +380,73 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "num" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", + "serde", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", + "serde", +] + [[package]] name = "num-traits" version = "0.2.19" diff --git a/journal/Cargo.toml b/journal/Cargo.toml index cde16f8..b4b6dd9 100644 --- a/journal/Cargo.toml +++ b/journal/Cargo.toml @@ -9,3 +9,4 @@ serde_json = "1.0.132" chrono = { version = "0.4.38", features = ["serde"] } psychonaut_journal_types = { path = "../psychonaut_journal_types" } rand = "0.8.5" +fraction = { version = "0.15.3", features = ["with-serde-support"] } diff --git a/journal/src/journal.rs b/journal/src/journal.rs index e670ad3..6dea1e1 100644 --- a/journal/src/journal.rs +++ b/journal/src/journal.rs @@ -1,5 +1,6 @@ use crate::types::{ - AdministrationRoute, Consumer, CustomUnit, Ingestion, Session, Substance, Unit, + AdministrationRoute, Consumer, CustomUnit, Ingestion, Session, Substance, SubstanceIngestion, + Unit, }; pub type JournalType = Box; @@ -8,7 +9,7 @@ pub trait Journal { fn get_custom_unit(&self, id: i32) -> Option; fn get_session(&self, id: i32) -> Option; fn get_session_ingestions(&self, id: i32) -> Option>; - fn get_session_ingestions_by( + fn get_session_substance_ingestions_by( &self, id: i32, substance_filter: Option<&Vec>, @@ -23,7 +24,7 @@ pub trait Journal { fn set_substance(&mut self, name: &String, substance: Substance); fn first_session_by_title(&self, title: &str) -> Option; - fn resolve_unit(&self, ingestion: &Ingestion) -> Option; + fn resolve_substance_unit(&self, ingestion: &SubstanceIngestion) -> Option; fn save(&self) -> Result<(), Box>; } diff --git a/journal/src/journal/json_journal.rs b/journal/src/journal/json_journal.rs index e921b1e..4da5a04 100644 --- a/journal/src/journal/json_journal.rs +++ b/journal/src/journal/json_journal.rs @@ -1,7 +1,8 @@ use std::{collections::HashMap, fs::File}; use crate::types::{ - AdministrationRoute, Consumer, CustomUnit, Ingestion, Session, Substance, Unit, + AdministrationRoute, Consumer, CustomUnit, Ingestion, IngestionKind, Session, Substance, + SubstanceIngestion, Unit, }; use super::{Journal, JournalType}; @@ -68,7 +69,7 @@ impl Journal for JSONJournal { self.data.ingestions.get(&id).cloned() } - fn get_session_ingestions_by( + fn get_session_substance_ingestions_by( &self, id: i32, substance_filter: Option<&Vec>, @@ -80,6 +81,17 @@ impl Journal for JSONJournal { .clone() .into_iter() .filter(|ingestion| { + if let Some(consumer_filter) = consumer_filter { + if !consumer_filter.contains(&ingestion.consumer) { + return false; + } + } + + let ingestion = match &ingestion.kind { + IngestionKind::Substance(ingestion) => ingestion, + _ => return false, + }; + if let Some(substance_filter) = substance_filter { if !substance_filter.contains(&ingestion.substance_name) { return false; @@ -92,12 +104,6 @@ impl Journal for JSONJournal { } } - if let Some(consumer_filter) = consumer_filter { - if !consumer_filter.contains(&ingestion.consumer) { - return false; - } - } - true }) .collect::>(); @@ -112,7 +118,7 @@ impl Journal for JSONJournal { self.data.substances.get(name).cloned() } - fn resolve_unit(&self, ingestion: &Ingestion) -> Option { + fn resolve_substance_unit(&self, ingestion: &SubstanceIngestion) -> Option { match ingestion.custom_unit_id { None => match self.get_substance(&ingestion.substance_name) { Some(substance) => Some(Unit::Simple(substance.unit)), diff --git a/journal/src/types/ingestion.rs b/journal/src/types/ingestion.rs index 6d0cb29..ea8afff 100644 --- a/journal/src/types/ingestion.rs +++ b/journal/src/types/ingestion.rs @@ -5,19 +5,21 @@ use super::{dose::Dose, from_unix_millis, AdministrationRoute, Consumer}; #[derive(PartialEq, Default, Debug, Clone)] #[derive(serde::Serialize, serde::Deserialize)] pub struct Ingestion { - pub substance_name: String, pub ingestion_time: DateTime, pub creation_time: DateTime, - pub dose: Dose, - pub custom_unit_id: Option, - pub roa: AdministrationRoute, pub consumer: Consumer, pub notes: String, - pub stomach_fullness: Option, + pub kind: IngestionKind, } +#[derive(PartialEq, Default, Debug, Clone)] +#[derive(serde::Serialize, serde::Deserialize)] +#[serde(tag = "type", rename_all = "lowercase")] pub enum IngestionKind { + #[default] + Unknown, Substance(SubstanceIngestion), + Sustenance(SustenanceIngestion), } #[derive(PartialEq, Default, Debug, Clone)] @@ -27,36 +29,45 @@ pub struct SubstanceIngestion { pub dose: Dose, pub custom_unit_id: Option, pub roa: AdministrationRoute, - pub consumer: Consumer, - pub notes: String, pub stomach_fullness: Option, } +#[derive(PartialEq, Default, Debug, Clone)] +#[derive(serde::Serialize, serde::Deserialize)] +pub struct SustenanceIngestion { + pub sustenance_name: String, + pub sustenance_category: String, + pub amount: (u8, u8, u8), +} + impl From for Ingestion { fn from(ingestion: psychonaut_journal_types::Ingestion) -> Self { Ingestion { - substance_name: ingestion.substance_name, ingestion_time: from_unix_millis(ingestion.ingestion_time), creation_time: from_unix_millis(ingestion.creation_time), - dose: { - if ingestion.estimate_standard_deviation.is_some() { - Dose::new_deviation( - ingestion.dose.unwrap(), - ingestion.estimate_standard_deviation.unwrap(), - ) - } else if ingestion.is_estimate && ingestion.dose.is_some() { - Dose::new_estimate(ingestion.dose.unwrap()) - } else if ingestion.dose.is_some() { - Dose::new_precise(ingestion.dose.unwrap()) - } else { - Dose::new_unknown() - } - }, + kind: IngestionKind::Substance(SubstanceIngestion { + substance_name: ingestion.substance_name, + dose: { + if ingestion.estimate_standard_deviation.is_some() { + Dose::new_deviation( + ingestion.dose.unwrap(), + ingestion.estimate_standard_deviation.unwrap(), + ) + } else if ingestion.is_estimate && ingestion.dose.is_some() { + Dose::new_estimate(ingestion.dose.unwrap()) + } else if ingestion.dose.is_some() { + Dose::new_precise(ingestion.dose.unwrap()) + } else { + Dose::new_unknown() + } + }, - custom_unit_id: ingestion.custom_unit_id, + custom_unit_id: ingestion.custom_unit_id, - roa: ingestion.roa, + roa: ingestion.roa, + stomach_fullness: ingestion.stomach_fullness, + }), consumer: match ingestion.consumer_name { Some(name) => Consumer::Named(name), @@ -64,14 +75,17 @@ impl From for Ingestion { }, notes: ingestion.notes, - stomach_fullness: ingestion.stomach_fullness, } } } #[cfg(test)] mod tests { - use crate::types::{from_unix_millis, AdministrationRoute, Consumer, Dose}; + use crate::types::{ + from_unix_millis, + ingestion::{IngestionKind, SubstanceIngestion}, + AdministrationRoute, Consumer, Dose, + }; use super::Ingestion; use psychonaut_journal_types::Ingestion as PsychonautIngestion; @@ -94,15 +108,17 @@ mod tests { stomach_fullness: None, }), Ingestion { - substance_name: "Caffeine".to_string(), ingestion_time: from_unix_millis(0), creation_time: from_unix_millis(0), - dose: Dose::new_precise(10.0), - custom_unit_id: None, - roa: AdministrationRoute::Oral, + kind: IngestionKind::Substance(SubstanceIngestion { + substance_name: "Caffeine".to_string(), + dose: Dose::new_precise(10.0), + custom_unit_id: None, + roa: AdministrationRoute::Oral, + stomach_fullness: None + }), consumer: Consumer::Default, notes: "".to_string(), - stomach_fullness: None } ); } diff --git a/journal/src/types/mod.rs b/journal/src/types/mod.rs index bf0b123..51a3ad5 100644 --- a/journal/src/types/mod.rs +++ b/journal/src/types/mod.rs @@ -13,7 +13,7 @@ mod consumer; pub use consumer::Consumer; mod ingestion; -pub use ingestion::Ingestion; +pub use ingestion::{Ingestion, IngestionKind, SubstanceIngestion}; mod substance; pub use substance::Substance; diff --git a/journal_cli/src/display.rs b/journal_cli/src/display.rs index 6f22954..78ad58f 100644 --- a/journal_cli/src/display.rs +++ b/journal_cli/src/display.rs @@ -1,9 +1,9 @@ use journal::{ journal::JournalType, - types::{format_dose, Consumer, Session}, + types::{format_dose, Consumer, IngestionKind, Session}, }; -use crate::formatting::{format_ingestion_roa, format_ingestion_time}; +use crate::formatting::{format_ingestion_time, format_substance_ingestion_roa}; pub fn print_ingestion_log( journal: &JournalType, @@ -12,30 +12,23 @@ pub fn print_ingestion_log( consumer_filter: Option<&Vec>, ) { for ingestion in journal - .get_session_ingestions(session.id) + .get_session_substance_ingestions_by(session.id, substance_filter, None, consumer_filter) .expect("could not find ingestions for session") .iter() { - if let Some(substance_filter) = substance_filter { - if !substance_filter.contains(&ingestion.substance_name) { - continue; - } - } + let substance_ingestion = match &ingestion.kind { + IngestionKind::Substance(substance_ingestion) => substance_ingestion, + _ => continue, + }; - if let Some(consumer_filter) = consumer_filter { - if !consumer_filter.contains(&ingestion.consumer) { - continue; - } - } - - let unit = journal.resolve_unit(ingestion).unwrap(); + let unit = journal.resolve_substance_unit(substance_ingestion).unwrap(); // println!("{:#?} {:#?}", &ingestion, &custom_unit); println!( "{}|{}|{}|{}|{}", - ingestion.substance_name, - format_dose(&ingestion.dose, &unit), - format_ingestion_roa(ingestion, &unit), + substance_ingestion.substance_name, + format_dose(&substance_ingestion.dose, &unit), + format_substance_ingestion_roa(substance_ingestion, &unit), ingestion.consumer, format_ingestion_time(ingestion) ) diff --git a/journal_cli/src/formatting.rs b/journal_cli/src/formatting.rs index 1137c1a..8b525f8 100644 --- a/journal_cli/src/formatting.rs +++ b/journal_cli/src/formatting.rs @@ -1,4 +1,4 @@ -use journal::types::{Ingestion, Session, Unit}; +use journal::types::{Ingestion, Session, SubstanceIngestion, Unit}; pub fn format_session_title(session: &Session) -> String { format!("{}: {}", session.title, session.creation_time) @@ -8,7 +8,7 @@ pub fn format_ingestion_time(ingestion: &Ingestion) -> String { ingestion.ingestion_time.format("%a %I:%M %p").to_string() } -pub fn format_ingestion_roa(ingestion: &Ingestion, unit: &Unit) -> String { +pub fn format_substance_ingestion_roa(ingestion: &SubstanceIngestion, unit: &Unit) -> String { if let Unit::Custom(unit) = unit { format!("{:?} ({})", ingestion.roa, &unit.name) } else { @@ -43,11 +43,11 @@ mod tests { } #[test] - fn format_ingestion_roa() { - let result = super::format_ingestion_roa( - &Ingestion { + fn format_substance_ingestion_roa() { + let result: String = super::format_substance_ingestion_roa( + &SubstanceIngestion { roa: AdministrationRoute::Oral, - ..Ingestion::default() + ..SubstanceIngestion::default() }, &Unit::default(), ); @@ -56,10 +56,10 @@ mod tests { #[test] fn format_ingestion_roa_with_custom_unit() { - let result = super::format_ingestion_roa( - &Ingestion { + let result = super::format_substance_ingestion_roa( + &SubstanceIngestion { roa: AdministrationRoute::Oral, - ..Ingestion::default() + ..SubstanceIngestion::default() }, &Unit::Custom(CustomUnit { name: "32mg/ml".to_string(),