diff --git a/.idea/runConfigurations/Install_CLI__Production_.xml b/.idea/runConfigurations/Install_CLI__Production_.xml
new file mode 100644
index 00000000..c6c777c9
--- /dev/null
+++ b/.idea/runConfigurations/Install_CLI__Production_.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/apps/cli/Cargo.lock b/apps/cli/Cargo.lock
index 5520ba7b..bc870dff 100644
--- a/apps/cli/Cargo.lock
+++ b/apps/cli/Cargo.lock
@@ -681,6 +681,15 @@ version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
+[[package]]
+name = "coolor"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "37e93977247fb916abeee1ff8c6594c9b421fd9c26c9b720a3944acb2a7de27b"
+dependencies = [
+ "crossterm",
+]
+
[[package]]
name = "core-foundation"
version = "0.9.4"
@@ -721,6 +730,73 @@ version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5"
+[[package]]
+name = "crokey"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b48209802ec5862bb034cb16719eec24d1c759e62921be7d3c899d0d85f3344b"
+dependencies = [
+ "crokey-proc_macros",
+ "crossterm",
+ "once_cell",
+ "serde",
+ "strict",
+]
+
+[[package]]
+name = "crokey-proc_macros"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "397d3c009d8df93c4b063ddaa44a81ee7098feb056f99b00896c36e2cee9a9f7"
+dependencies = [
+ "crossterm",
+ "proc-macro2",
+ "quote",
+ "strict",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "crossbeam"
+version = "0.8.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8"
+dependencies = [
+ "crossbeam-channel",
+ "crossbeam-deque",
+ "crossbeam-epoch",
+ "crossbeam-queue",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-channel"
+version = "0.5.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2"
+dependencies = [
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-deque"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d"
+dependencies = [
+ "crossbeam-epoch",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-epoch"
+version = "0.9.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
+dependencies = [
+ "crossbeam-utils",
+]
+
[[package]]
name = "crossbeam-queue"
version = "0.3.11"
@@ -736,6 +812,31 @@ version = "0.8.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
+[[package]]
+name = "crossterm"
+version = "0.27.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df"
+dependencies = [
+ "bitflags 2.5.0",
+ "crossterm_winapi",
+ "libc",
+ "mio",
+ "parking_lot",
+ "signal-hook",
+ "signal-hook-mio",
+ "winapi",
+]
+
+[[package]]
+name = "crossterm_winapi"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b"
+dependencies = [
+ "winapi",
+]
+
[[package]]
name = "crypto-common"
version = "0.1.6"
@@ -1447,6 +1548,29 @@ dependencies = [
"log",
]
+[[package]]
+name = "lazy-regex"
+version = "3.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d12be4595afdf58bd19e4a9f4e24187da2a66700786ff660a418e9059937a4c"
+dependencies = [
+ "lazy-regex-proc_macros",
+ "once_cell",
+ "regex",
+]
+
+[[package]]
+name = "lazy-regex-proc_macros"
+version = "3.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44bcd58e6c97a7fcbaffcdc95728b393b8d98933bfadad49ed4097845b57ef0b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "regex",
+ "syn 2.0.66",
+]
+
[[package]]
name = "lazy_static"
version = "1.4.0"
@@ -1539,12 +1663,32 @@ dependencies = [
"digest",
]
+[[package]]
+name = "measurements"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f5b734b4e8187ea5777bc29c086f0970a27d8de42061b48f5af32cafc0ca904b"
+dependencies = [
+ "libm",
+ "regex",
+ "serde",
+]
+
[[package]]
name = "memchr"
version = "2.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
+[[package]]
+name = "minimad"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9c5d708226d186590a7b6d4a9780e2bdda5f689e0d58cd17012a298efd745d2"
+dependencies = [
+ "once_cell",
+]
+
[[package]]
name = "minimal-lexical"
version = "0.2.1"
@@ -1560,6 +1704,18 @@ dependencies = [
"adler",
]
+[[package]]
+name = "mio"
+version = "0.8.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
+dependencies = [
+ "libc",
+ "log",
+ "wasi",
+ "windows-sys 0.48.0",
+]
+
[[package]]
name = "nalgebra"
version = "0.29.0"
@@ -1626,6 +1782,7 @@ dependencies = [
"lazy_static",
"libsqlite3-sys",
"log",
+ "measurements",
"neuronek-database-client",
"rust-embed",
"sea-orm",
@@ -1637,6 +1794,7 @@ dependencies = [
"strsim 0.11.1",
"structopt",
"tabled",
+ "termimad",
"terminal_size",
"tokio",
"uom",
@@ -2658,6 +2816,36 @@ dependencies = [
"lazy_static",
]
+[[package]]
+name = "signal-hook"
+version = "0.3.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801"
+dependencies = [
+ "libc",
+ "signal-hook-registry",
+]
+
+[[package]]
+name = "signal-hook-mio"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af"
+dependencies = [
+ "libc",
+ "mio",
+ "signal-hook",
+]
+
+[[package]]
+name = "signal-hook-registry"
+version = "1.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
+dependencies = [
+ "libc",
+]
+
[[package]]
name = "signature"
version = "2.2.0"
@@ -2994,6 +3182,12 @@ dependencies = [
"thread_local",
]
+[[package]]
+name = "strict"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f42444fea5b87a39db4218d9422087e66a85d0e7a0963a439b07bcdf91804006"
+
[[package]]
name = "stringprep"
version = "0.1.5"
@@ -3148,6 +3342,22 @@ dependencies = [
"winapi-util",
]
+[[package]]
+name = "termimad"
+version = "0.29.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aab6c8572830b10362f27e242c7c5e749f062ec310b76a0d0b56670eca81f28e"
+dependencies = [
+ "coolor",
+ "crokey",
+ "crossbeam",
+ "lazy-regex",
+ "minimad",
+ "serde",
+ "thiserror",
+ "unicode-width",
+]
+
[[package]]
name = "terminal_size"
version = "0.3.0"
diff --git a/apps/cli/Cargo.toml b/apps/cli/Cargo.toml
index 04297035..504c0f5c 100644
--- a/apps/cli/Cargo.toml
+++ b/apps/cli/Cargo.toml
@@ -42,6 +42,8 @@ human-panic = "2.0.0"
clap_complete = "4.4.10"
dateless = "0.3.1"
iso8601-duration = { version = "0.2.0",features = ["serde", "chrono"] }
+measurements = { version = "0.11.0",features = ["serde", "std", "from_str"] }
+termimad = "0.29.2"
[features]
default = []
diff --git a/apps/cli/src/cli/main.rs b/apps/cli/src/cli/main.rs
index a0bbec46..7ac2f20a 100644
--- a/apps/cli/src/cli/main.rs
+++ b/apps/cli/src/cli/main.rs
@@ -62,7 +62,7 @@ pub async fn cli() {
stderrlog::new()
// .module(module_path!())
.show_level(true)
- .verbosity(2)
+ .verbosity(0)
.show_module_names(true)
.init()
.unwrap();
diff --git a/apps/cli/src/core/route_of_administration_dosage.rs b/apps/cli/src/core/dosage.rs
similarity index 53%
rename from apps/cli/src/core/route_of_administration_dosage.rs
rename to apps/cli/src/core/dosage.rs
index d87269ba..7105f043 100644
--- a/apps/cli/src/core/route_of_administration_dosage.rs
+++ b/apps/cli/src/core/dosage.rs
@@ -2,8 +2,7 @@ use std::ops::{Range, RangeFrom, RangeTo};
use std::str::FromStr;
use serde::{Deserialize, Serialize};
-
-use crate::core::mass::Mass;
+pub type Dosage = measurements::Mass;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Eq, Hash, Copy)]
#[serde(rename_all = "snake_case")]
@@ -49,25 +48,56 @@ impl From for String {
#[derive(Debug, PartialEq, Clone)]
pub enum DosageRange {
- From(RangeFrom),
- To(RangeTo),
- Inclusive(Range),
+ Heavy(RangeFrom),
+ Threshold(RangeTo),
+ Inclusive(Range),
}
+
impl DosageRange {
- pub fn contains(&self, mass: &Mass) -> bool {
+ pub fn contains(&self, mass: Dosage) -> bool {
match self {
- DosageRange::From(range) => &range.start <= mass,
- DosageRange::To(range) => mass <= &range.end,
- DosageRange::Inclusive(range) => &range.start <= mass && mass <= &range.end,
+ DosageRange::Heavy(range) => range.start <= mass,
+ DosageRange::Threshold(range) => mass <= range.end,
+ DosageRange::Inclusive(range) => range.start <= mass && mass <= range.end,
}
}
}
+
+extern crate measurements;
+use measurements::*;
+
+pub fn test_measurements() {
+ for power in -12..12 {
+ let val: f64 = 123.456 * (10f64.powf(f64::from(power)));
+ println!("10^{}...", power);
+ println!("Temp of {0:.3} outside", Temperature::from_kelvin(val));
+ println!("Distance of {0:.3}", Length::from_meters(val));
+ println!("Pressure of {0:.3}", Pressure::from_millibars(val));
+ println!("Volume of {0:.3}", Volume::from_litres(val));
+ println!("Mass of {0:.3}", Mass::from_kilograms(val));
+ println!("Speed of {0:.3}", Speed::from_meters_per_second(val));
+ println!(
+ "Acceleration of {0:.3}",
+ Acceleration::from_meters_per_second_per_second(val)
+ );
+ println!("Energy of {0:.3}", Energy::from_joules(val));
+ println!("Power of {0:.3}", Power::from_watts(val));
+ println!("Force of {0:.3}", Force::from_newtons(val));
+ println!("Force of {0:.3}", Torque::from_newton_metres(val));
+ println!(
+ "Force of {0:.3}",
+ AngularVelocity::from_radians_per_second(val)
+ );
+ println!("Data size is {0:.3}", Data::from_octets(val));
+ }
+}
+
#[derive(Debug, Clone)]
pub struct RouteOfAdministrationDosage {
pub id: String,
pub route_of_administration_id: String,
pub dosage_classification: DosageClassification,
pub dosage_range: DosageRange,
-}
+}
\ No newline at end of file
diff --git a/apps/cli/src/core/mass.rs b/apps/cli/src/core/mass.rs
index 35d8342b..5a9967df 100644
--- a/apps/cli/src/core/mass.rs
+++ b/apps/cli/src/core/mass.rs
@@ -1,18 +1,9 @@
-use uom::si::f32::Mass as MassUom;
-use uom::si::mass::{gram, kilogram, milligram};
+use std::num::ParseFloatError;
+use std::str::FromStr;
+use crate::core::dosage::Dosage;
-pub type Mass = MassUom;
+pub type Mass = Dosage;
-// Implement functionality to parse Mass from string in format "1.0 kg", "1.0 kg", "50mg" "50 mg" and so on...
-
-pub fn deserialize_mass_unit(mass_str: &str) -> Result {
- let mut mass_str = mass_str.split_whitespace();
- let mass = mass_str.next().unwrap().parse::().unwrap();
- let unit = mass_str.next().unwrap();
- match unit {
- "kg" => Ok(Mass::new::(mass)),
- "g" => Ok(Mass::new::(mass)),
- "mg" => Ok(Mass::new::(mass)),
- _ => Err("Invalid unit"),
- }
+pub fn deserialize_dosage(mass_str: &str) -> Result {
+ return Dosage::from_str(mass_str);
}
diff --git a/apps/cli/src/core/mod.rs b/apps/cli/src/core/mod.rs
index 6d9ef1c2..1b19a7ed 100644
--- a/apps/cli/src/core/mod.rs
+++ b/apps/cli/src/core/mod.rs
@@ -2,5 +2,5 @@ pub mod ingestion;
pub mod mass;
pub mod phase;
pub mod route_of_administration;
-pub mod route_of_administration_dosage;
+pub mod dosage;
pub mod substance;
diff --git a/apps/cli/src/core/route_of_administration.rs b/apps/cli/src/core/route_of_administration.rs
index 7293cb64..45e2bb24 100644
--- a/apps/cli/src/core/route_of_administration.rs
+++ b/apps/cli/src/core/route_of_administration.rs
@@ -3,12 +3,8 @@ use std::str::FromStr;
use serde::{Deserialize, Serialize};
use strsim::normalized_levenshtein;
-
-use crate::core::mass::Mass;
use crate::core::phase::{Phase, PhaseClassification};
-use crate::core::route_of_administration_dosage::{
- DosageClassification, RouteOfAdministrationDosage,
-};
+use crate::core::dosage::{Dosage, DosageClassification, RouteOfAdministrationDosage};
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Eq, Hash)]
#[serde(rename_all = "snake_case")]
@@ -103,14 +99,14 @@ pub struct RouteOfAdministration {
}
pub fn get_dosage_classification_by_mass_and_route_of_administration(
- mass: &Mass,
+ mass: &Dosage,
route_of_administration: &RouteOfAdministration,
) -> Result {
for (classification, dosage) in route_of_administration.dosages.iter() {
- if dosage.dosage_range.contains(mass) {
+ let contains = dosage.dosage_range.contains(mass.clone());
+ if contains {
return Ok(*classification);
}
}
-
Err("No classification found for the given mass and route of administration")
-}
+}
\ No newline at end of file
diff --git a/apps/cli/src/ingestion.rs b/apps/cli/src/ingestion.rs
index 4acb7e5b..41ad4545 100644
--- a/apps/cli/src/ingestion.rs
+++ b/apps/cli/src/ingestion.rs
@@ -5,14 +5,16 @@ use chrono_english::{parse_date_string, Dialect};
use chrono_humanize::HumanTime;
use db::ingestion::ActiveModel;
use db::prelude::Ingestion;
+use measurements::Measurement;
use sea_orm::{ActiveValue, DatabaseConnection, EntityTrait, QueryTrait};
use serde::{Deserialize, Serialize};
use serde_json::to_string;
use tabled::{Table, Tabled};
use uom::num::ToPrimitive;
use uom::si::mass::milligram;
+use crate::core::dosage::Dosage;
-use crate::core::mass::deserialize_mass_unit;
+use crate::core::mass::deserialize_dosage;
use crate::core::route_of_administration::RouteOfAdministrationClassification;
use crate::ingestion_analyzer::analyze_future_ingestion;
use crate::service::substance::search_substance;
@@ -22,9 +24,7 @@ pub async fn create_ingestion(db: &DatabaseConnection, create_ingestion: CreateI
let parsed_time = parse_date_string(&create_ingestion.ingested_at, Utc::now(), Dialect::Us)
.unwrap_or_else(|_| Utc::now());
- let parsed_mass = deserialize_mass_unit(&create_ingestion.dosage).unwrap();
-
- println!("{:?}", parsed_mass);
+ let parsed_mass = deserialize_dosage(&create_ingestion.dosage).unwrap();
let substance = match search_substance(db, &create_ingestion.substance_name).await {
Some(substance) => substance,
@@ -41,9 +41,9 @@ pub async fn create_ingestion(db: &DatabaseConnection, create_ingestion: CreateI
administration_route: ActiveValue::Set(Option::from(
to_string(&create_ingestion.route_of_administration).unwrap(),
)),
- dosage_unit: ActiveValue::Set(Option::from("mg".to_owned())),
+ dosage_unit: ActiveValue::Set(Option::from("kg".to_owned())),
dosage_amount: ActiveValue::Set(Option::from(
- parsed_mass.get::().to_f32().unwrap() as f64,
+ parsed_mass.as_kilograms()
)),
ingestion_date: ActiveValue::Set(Option::from(parsed_time.naive_local())),
subject_id: ActiveValue::Set(Option::from(String::from("unknown"))),
diff --git a/apps/cli/src/ingestion_analyzer.rs b/apps/cli/src/ingestion_analyzer.rs
index c568ee01..08cf86f5 100644
--- a/apps/cli/src/ingestion_analyzer.rs
+++ b/apps/cli/src/ingestion_analyzer.rs
@@ -2,24 +2,24 @@
// and try to extract and provide as much information as it's
// possible. This is a very important part of the application
-use std::fmt::Debug;
-use std::ops::Deref;
+use std::fmt::{Debug, Display};
use std::time::Duration;
-use chrono::{Local};
+use chrono::{Local, TimeZone};
use chrono_english::{Dialect, parse_date_string};
use chrono_humanize::HumanTime;
use log::{debug, error};
+use measurements::Measurement;
use serde::{Deserialize, Serialize};
-
+use termimad::MadSkin;
use crate::core::ingestion::{IngestionPhase, IngestionPhases};
-use crate::core::mass::{deserialize_mass_unit, Mass};
+use crate::core::mass::{deserialize_dosage, Mass};
use crate::core::phase::PhaseClassification;
use crate::core::route_of_administration::{
get_dosage_classification_by_mass_and_route_of_administration,
RouteOfAdministrationClassification,
};
-use crate::core::route_of_administration_dosage::DosageClassification;
+use crate::core::dosage::{Dosage, DosageClassification};
use crate::core::substance::{
get_phases_by_route_of_administration,
get_route_of_administration_by_classification_and_substance,
@@ -63,7 +63,7 @@ pub async fn analyze_future_ingestion(
});
// Parse mass from input
- let ingestion_mass = deserialize_mass_unit(&create_ingestion.dosage).unwrap_or_else(|_| {
+ let ingestion_mass = deserialize_dosage(&create_ingestion.dosage).unwrap_or_else(|_| {
error!("Analysis failed: Invalid mass");
panic!("Analysis failed: Invalid mass unit");
});
@@ -74,7 +74,7 @@ pub async fn analyze_future_ingestion(
)
.unwrap_or_else(|_| {
error!("Analysis failed: Dosage classification not found");
- panic!("Analysis failed: Dosage classification not found");
+ return DosageClassification::Unknown;
});
// Calculate ingestion plan based on phase information
@@ -82,11 +82,11 @@ pub async fn analyze_future_ingestion(
let phases = get_phases_by_route_of_administration(&route_of_administration);
let total_duration = phases.iter().fold(Duration::default(), |acc, phase| {
- if phase.phase_classification == PhaseClassification::Afterglow {
- return acc;
+ return if phase.phase_classification == PhaseClassification::Afterglow {
+ acc
} else {
let added = acc + phase.duration_range.end;
- return added;
+ added
}
});
@@ -134,28 +134,52 @@ pub async fn analyze_future_ingestion(
}
pub fn pretty_print_ingestion_analysis(ingestion_analysis: &IngestionAnalysis) {
- println!("{}", "-".repeat(40));
- println!("Ingestion Analysis for {:?}", ingestion_analysis.substance_name);
- println!("Route of Administration: {:?}", ingestion_analysis.route_of_administration_classification);
- println!("Dosage: {:?}", ingestion_analysis.dosage);
- println!("Dosage Classification: {:?}", ingestion_analysis.dosage_classification);
- println!("Total Duration: {:?}", HumanTime::from(chrono::Duration::from_std(ingestion_analysis.total_duration).unwrap()).to_string());
- println!("Phases:");
- // Convert HashMap to Vec
+ let mut markdown = String::new();
+ markdown.push_str(&format!(
+ "{}", "-".repeat(40) + "\n"
+ ));
+ markdown.push_str(&format!(
+ "Ingestion Analysis for **{}**\n",
+ ingestion_analysis.substance_name
+ ));
+ markdown.push_str(&format!(
+ "Route of Administration: **{:?}**\n",
+ ingestion_analysis.route_of_administration_classification
+ ));
+ markdown.push_str(&format!(
+ "Dosage: **{0:.0}**\n",
+ ingestion_analysis.dosage
+ ));
+ markdown.push_str(&format!(
+ "Dosage Classification: **{:?}**\n",
+ ingestion_analysis.dosage_classification
+ ));
+ markdown.push_str(&format!(
+ "Total Duration: **{:?}**\n",
+ HumanTime::from(chrono::Duration::from_std(ingestion_analysis.total_duration).unwrap()).to_string()
+ ));
+ markdown.push_str(&format!(
+ "Phases:\n"
+ ));
+
let mut phases: Vec<(&PhaseClassification, &IngestionPhase)> = ingestion_analysis.phases.iter().collect();
-
- // Sort Vec based on PhaseClassification
phases.sort_by_key(|&(classification, _)| *classification);
-
- // Iterate over sorted Vec
+
for (phase_classification, phase) in phases {
- println!("* {:?}: {:?}", phase_classification, HumanTime::from(phase.start_time).to_string());
+ markdown.push_str(&format!(
+ " ▶ **{:?}**: {:?}\n",
+ phase_classification,
+ HumanTime::from(phase.start_time).to_string()
+ ));
}
- println!("{}", "-".repeat(40));
-}
-
+ markdown.push_str(&format!(
+ "{}", "-".repeat(40) + "\n"
+ ));
+ let skin = MadSkin::default();
+ println!("{}", skin.term_text(&markdown));
+}
#[cfg(test)]
mod tests {
@@ -163,7 +187,7 @@ mod tests {
use crate::core::phase::PhaseClassification;
use crate::core::route_of_administration::RouteOfAdministrationClassification;
- use crate::core::route_of_administration_dosage::DosageClassification;
+ use crate::core::dosage::DosageClassification;
use crate::ingestion::CreateIngestion;
use crate::ingestion_analyzer::analyze_future_ingestion;
diff --git a/apps/cli/src/main.rs b/apps/cli/src/main.rs
index 62e1d210..818f07af 100644
--- a/apps/cli/src/main.rs
+++ b/apps/cli/src/main.rs
@@ -3,6 +3,7 @@
use async_std::task;
use crate::cli::main::cli;
+use crate::core::dosage::test_measurements;
mod cli;
mod core;
diff --git a/apps/cli/src/service/substance.rs b/apps/cli/src/service/substance.rs
index e801b556..a1d62c09 100644
--- a/apps/cli/src/service/substance.rs
+++ b/apps/cli/src/service/substance.rs
@@ -15,7 +15,7 @@ use crate::core::route_of_administration::{
RouteOfAdministration, RouteOfAdministrationClassification, RouteOfAdministrationDosages,
RouteOfAdministrationPhases,
};
-use crate::core::route_of_administration_dosage::{
+use crate::core::dosage::{
DosageClassification, DosageRange, RouteOfAdministrationDosage,
};
use crate::core::substance::{RoutesOfAdministration, Substance};
@@ -58,14 +58,14 @@ pub async fn get_substance_by_name(name: &str) -> Option {
format!("{:?} {}", d.upper_bound_amount.unwrap(), mass_unit).as_str(),
)
.unwrap();
- DosageRange::To(RangeTo { end: max_mass })
+ DosageRange::Threshold(RangeTo { end: max_mass })
}
DosageClassification::Heavy => {
let min_mass = Mass::from_str(
format!("{:?} {}", d.lower_bound_amount.unwrap(), mass_unit).as_str(),
)
.unwrap();
- DosageRange::From(RangeFrom { start: min_mass })
+ DosageRange::Heavy(RangeFrom { start: min_mass })
}
_ => {
let min_mass = Mass::from_str(