From 313507f60e6dca33c87bac2966e34c705f6082f6 Mon Sep 17 00:00:00 2001 From: chaos Date: Fri, 22 Nov 2024 22:00:42 +0000 Subject: [PATCH] update --- Cargo.lock | 191 ++++++++++++++++++- journal/src/journal.rs | 76 ++++++-- journal/src/types/dose/add.rs | 27 +++ journal/src/types/dose/multiply.rs | 107 ++++++++++- journal/src/types/dose_with_unit.rs | 4 +- journal/src/types/estimate.rs | 3 +- journal_cli/Cargo.toml | 2 +- journal_cli/src/commands/print_experience.rs | 4 +- 8 files changed, 391 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2d0de34..f1a908a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -53,7 +53,7 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -63,7 +63,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" dependencies = [ "anstyle", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -72,6 +72,12 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + [[package]] name = "bumpalo" version = "3.16.0" @@ -166,6 +172,54 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "csv" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdc4883a9c96732e4733212c01447ebd805833b7275a73ca3ee080fd77afdaf" +dependencies = [ + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" +dependencies = [ + "memchr", +] + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + [[package]] name = "getrandom" version = "0.2.15" @@ -183,6 +237,12 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + [[package]] name = "iana-time-zone" version = "0.1.61" @@ -206,6 +266,17 @@ dependencies = [ "cc", ] +[[package]] +name = "is-terminal" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.1" @@ -237,12 +308,28 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + [[package]] name = "libc" version = "0.2.162" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags", + "libc", +] + [[package]] name = "log" version = "0.4.22" @@ -279,6 +366,20 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "prettytable-rs" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eea25e07510aa6ab6547308ebe3c036016d162b8da920dbb079e3ba8acf3d95a" +dependencies = [ + "csv", + "encode_unicode", + "is-terminal", + "lazy_static", + "term", + "unicode-width", +] + [[package]] name = "proc-macro2" version = "1.0.89" @@ -295,6 +396,7 @@ dependencies = [ "chrono", "clap", "journal", + "prettytable-rs", "psychonaut_journal_types", "serde", "serde_json", @@ -346,6 +448,23 @@ dependencies = [ "getrandom", ] +[[package]] +name = "redox_users" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +dependencies = [ + "getrandom", + "libredox", + "thiserror", +] + +[[package]] +name = "rustversion" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" + [[package]] name = "ryu" version = "1.0.18" @@ -407,12 +526,49 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "term" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" +dependencies = [ + "dirs-next", + "rustversion", + "winapi", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "unicode-ident" version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + [[package]] name = "utf8parse" version = "0.2.2" @@ -480,6 +636,28 @@ version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows-core" version = "0.52.0" @@ -489,6 +667,15 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-sys" version = "0.59.0" diff --git a/journal/src/journal.rs b/journal/src/journal.rs index 4ceba26..31ffd88 100644 --- a/journal/src/journal.rs +++ b/journal/src/journal.rs @@ -1,15 +1,24 @@ use rand::Rng; -use crate::types::{CustomUnit, Experience, ExportFormat, Ingestion, Unit}; +use crate::types::{ + AdministrationRoute, Consumer, CustomUnit, Experience, ExportFormat, Ingestion, Unit, +}; pub type JournalType = Box; pub trait Journal { - fn get_custom_unit(&self, id: i64) -> Option<&CustomUnit>; - fn get_experience(&self, id: i64) -> Option<&Experience>; - fn get_experience_ingestions(&self, id: i64) -> Option<&Vec>; + fn get_custom_unit(&self, id: i64) -> Option; + fn get_experience(&self, id: i64) -> Option; + fn get_experience_ingestions(&self, id: i64) -> Option>; + fn get_experience_ingestions_by( + &self, + id: i64, + substance_filter: Option<&Vec>, + route_filter: Option<&Vec>, + consumer_filter: Option<&Vec>, + ) -> Option>; - fn first_experience_by_title(&self, title: &str) -> Option<&Experience>; + fn first_experience_by_title(&self, title: &str) -> Option; fn resolve_unit(&self, unit: &Unit) -> Unit; fn import_psychonaut(&mut self, data: psychonaut_journal_types::ExportData); @@ -18,16 +27,56 @@ pub trait Journal { pub type InMemJournal = ExportFormat; impl Journal for InMemJournal { - fn get_custom_unit(&self, id: i64) -> Option<&CustomUnit> { - self.custom_units.get(&id) + fn get_custom_unit(&self, id: i64) -> Option { + self.custom_units.get(&id).cloned() } - fn get_experience(&self, id: i64) -> Option<&Experience> { - self.experiences.get(&id) + fn get_experience(&self, id: i64) -> Option { + self.experiences.get(&id).cloned() } - fn get_experience_ingestions(&self, id: i64) -> Option<&Vec> { - self.ingestions.get(&id) + fn get_experience_ingestions(&self, id: i64) -> Option> { + self.ingestions.get(&id).cloned() + } + + fn get_experience_ingestions_by( + &self, + id: i64, + substance_filter: Option<&Vec>, + route_filter: Option<&Vec>, + consumer_filter: Option<&Vec>, + ) -> Option> { + if let Some(ingestions) = self.get_experience_ingestions(id) { + let ingestions = ingestions + .clone() + .into_iter() + .filter(|ingestion| { + if let Some(substance_filter) = substance_filter { + if !substance_filter.contains(&ingestion.substance_name) { + return false; + } + } + + if let Some(route_filter) = route_filter { + if !route_filter.contains(&ingestion.roa) { + return false; + } + } + + if let Some(consumer_filter) = consumer_filter { + if !consumer_filter.contains(&ingestion.consumer) { + return false; + } + } + + true + }) + .collect::>(); + + Some(ingestions) + } else { + None + } } fn resolve_unit(&self, unit: &Unit) -> Unit { @@ -40,16 +89,17 @@ impl Journal for InMemJournal { }, None => Unit::Custom { id: *id, - unit: self.get_custom_unit(*id).cloned(), + unit: self.get_custom_unit(*id), }, }, } } - fn first_experience_by_title(&self, title: &str) -> Option<&Experience> { + fn first_experience_by_title(&self, title: &str) -> Option { self.experiences .values() .find(|&experience| experience.title == title) + .cloned() } fn import_psychonaut(&mut self, data: psychonaut_journal_types::ExportData) { diff --git a/journal/src/types/dose/add.rs b/journal/src/types/dose/add.rs index 1d66d4d..12db2a8 100644 --- a/journal/src/types/dose/add.rs +++ b/journal/src/types/dose/add.rs @@ -52,6 +52,8 @@ impl Add<&Dose> for Dose { #[cfg(test)] mod tests { + use crate::types::StandardDeviation; + use super::{Dose, Estimation}; #[test] @@ -112,4 +114,29 @@ mod tests { } ); } + + #[test] + fn add_with_standard_deviation() { + assert_eq!( + Dose { + value: 10.0, + estimation: Estimation::StandardDeviation(StandardDeviation { + expectation: 10.0, + deviation: 10.0, + }), + ..Dose::default() + } + Dose { + value: 10.0, + ..Dose::default() + }, + Dose { + value: 20.0, + contains_unknown: false, + estimation: Estimation::StandardDeviation(StandardDeviation { + expectation: 10.0, + deviation: 10.0, + }), + } + ); + } } diff --git a/journal/src/types/dose/multiply.rs b/journal/src/types/dose/multiply.rs index c6acb32..c1cbe82 100644 --- a/journal/src/types/dose/multiply.rs +++ b/journal/src/types/dose/multiply.rs @@ -1,3 +1,5 @@ +use crate::types::StandardDeviation; + use super::{Dose, Estimation}; use std::ops::Mul; @@ -31,7 +33,26 @@ impl Mul<&Dose> for Dose { fn mul(self, rhs: &Self) -> Self::Output { let contains_unknown = self.contains_unknown || rhs.contains_unknown; - let estimation = match self.estimation * &rhs.estimation { + let estimation = match (self.estimation, &rhs.estimation) { + (Estimation::StandardDeviation(_), Estimation::StandardDeviation(_)) => { + self.estimation * &rhs.estimation + } + (_, Estimation::StandardDeviation(deviation)) => { + Estimation::StandardDeviation(StandardDeviation { + expectation: self.value * deviation.expectation, + deviation: deviation.deviation, + }) + } + (Estimation::StandardDeviation(deviation), _) => { + Estimation::StandardDeviation(StandardDeviation { + expectation: deviation.expectation * rhs.value, + deviation: deviation.deviation, + }) + } + _ => self.estimation * &rhs.estimation, + }; + + let estimation = match estimation { Estimation::Precise => { if contains_unknown { Estimation::Estimate @@ -39,6 +60,7 @@ impl Mul<&Dose> for Dose { Estimation::Precise } } + value => value, }; @@ -52,6 +74,8 @@ impl Mul<&Dose> for Dose { #[cfg(test)] mod tests { + use crate::types::StandardDeviation; + use super::{Dose, Estimation}; #[test] @@ -94,6 +118,87 @@ mod tests { ); } + #[test] + fn mul_with_lhs_standard_deviation() { + assert_eq!( + Dose { + value: 10.0, + estimation: Estimation::StandardDeviation(StandardDeviation { + expectation: 10.0, + deviation: 10.0 + }), + ..Dose::default() + } * Dose { + value: 10.0, + estimation: Estimation::Precise, + ..Dose::default() + }, + Dose { + value: 100.0, + estimation: Estimation::StandardDeviation(StandardDeviation { + expectation: 100.0, + deviation: 10.0 + }), + ..Dose::default() + } + ); + } + + #[test] + fn mul_with_rhs_standard_deviation() { + assert_eq!( + Dose { + value: 10.0, + estimation: Estimation::Precise, + ..Dose::default() + } * Dose { + value: 10.0, + estimation: Estimation::StandardDeviation(StandardDeviation { + expectation: 10.0, + deviation: 10.0 + }), + ..Dose::default() + }, + Dose { + value: 100.0, + estimation: Estimation::StandardDeviation(StandardDeviation { + expectation: 100.0, + deviation: 10.0 + }), + ..Dose::default() + } + ); + } + + #[test] + fn mul_with_standard_deviations() { + assert_eq!( + Dose { + value: 10.0, + estimation: Estimation::StandardDeviation(StandardDeviation { + expectation: 10.0, + deviation: 10.0 + }), + ..Dose::default() + } * Dose { + value: 10.0, + estimation: Estimation::StandardDeviation(StandardDeviation { + expectation: 10.0, + deviation: 10.0 + }), + ..Dose::default() + }, + Dose { + value: 100.0, + estimation: Estimation::StandardDeviation(StandardDeviation { + expectation: 100.0, + deviation: 173.0 + }), + ..Dose::default() + } + ); + } + #[test] fn mul_with_unknown() { assert_eq!( diff --git a/journal/src/types/dose_with_unit.rs b/journal/src/types/dose_with_unit.rs index fd375d1..0080f1c 100644 --- a/journal/src/types/dose_with_unit.rs +++ b/journal/src/types/dose_with_unit.rs @@ -64,7 +64,7 @@ impl Display for DoseWithUnitRefs<'_> { let unit = unit.clone().unwrap(); let unit_unit = Unit::Simple(unit.unit.clone()); - let ingestion_dose = dose * &unit.dose; + let ingestion_dose = &unit.dose * dose; let ingestion_unit = Unit::Simple(unit.original_unit.clone()); // ingestion dose @@ -169,7 +169,7 @@ mod tests { } #[test] - fn format_dose_standard_derivation() { + fn format_dose_standard_deviation() { let result = super::format_dose( &Dose { value: 0.0, diff --git a/journal/src/types/estimate.rs b/journal/src/types/estimate.rs index 04f821a..65a3ac6 100644 --- a/journal/src/types/estimate.rs +++ b/journal/src/types/estimate.rs @@ -1,4 +1,3 @@ - #[derive(PartialEq, Debug, Copy, Clone, Default)] pub enum Estimation { #[default] @@ -14,5 +13,5 @@ pub struct StandardDeviation { } mod add; -mod multiply; mod is; +mod multiply; diff --git a/journal_cli/Cargo.toml b/journal_cli/Cargo.toml index bccb28d..d8b4a51 100644 --- a/journal_cli/Cargo.toml +++ b/journal_cli/Cargo.toml @@ -14,7 +14,7 @@ psychonaut_journal_types = { path = "../psychonaut_journal_types" } chrono = { version = "0.4.38", features = ["serde"] } clap = { version = "4.5.21", features = ["derive", "env"] } #log = { version = "0.4.22", features = ["std", "serde"] } -#prettytable-rs = "0.10.0" +prettytable-rs = "0.10.0" serde = { version = "1.0.215", features = ["std", "derive", "serde_derive"] } serde_json = "1.0.132" #serde_with = "3.11.0" diff --git a/journal_cli/src/commands/print_experience.rs b/journal_cli/src/commands/print_experience.rs index ae43c5c..e90c995 100644 --- a/journal_cli/src/commands/print_experience.rs +++ b/journal_cli/src/commands/print_experience.rs @@ -53,14 +53,14 @@ pub fn print_experience( //println!("{:#?}", &experience); - println!("{}", format_experience_title(experience)); + println!("{}", format_experience_title(&experience)); let substance_filter = args.substance_filter.clone(); let consumer_filter = parse_consumer_filter(args.consumer_filter.clone()); print_ingestion_log( &journal, - experience, + &experience, substance_filter.as_ref(), consumer_filter.as_ref(), );