Remaining subcommands for substances

This commit is contained in:
xqtc 2024-10-12 01:09:44 +02:00
parent 51ad2bf67e
commit 8447e89f19
7 changed files with 189 additions and 80 deletions

View file

@ -3,8 +3,6 @@ use serde::Deserialize;
use std::fs;
use std::process::exit;
use crate::substances;
#[derive(Deserialize)]
pub struct Config {
pub save_dir: String,

View file

@ -1,16 +1,14 @@
use crate::ingestions_util::{
self, ensure_ingestion_files, get_dose_unit, get_ingestion_confirmation, get_ingestion_method,
ensure_ingestion_files, get_dose_unit, get_ingestion_confirmation, get_ingestion_method,
get_substance, get_user_datetime,
};
use chrono::{NaiveDateTime, Utc};
use color_eyre::Section;
use chrono::NaiveDateTime;
use inquire;
use serde::{self, Deserialize, Serialize};
use std::{collections::HashMap, process::exit};
use strum::{EnumIter, IntoEnumIterator};
use std::collections::HashMap;
use uuid::Uuid;
use crate::{config::INGESTIONS_FILE, substances::Substance};
use crate::config::INGESTIONS_FILE;
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Ingestion {
@ -77,7 +75,7 @@ pub fn add_ingestion() {
if confirm {
ingesstions_bytes_loaded_des.insert(Uuid::new_v4(), ingestion.clone());
let ingestion_ser = bincode::serialize(&ingesstions_bytes_loaded_des).unwrap();
std::fs::write(INGESTIONS_FILE.to_string(), ingestion_ser);
std::fs::write(INGESTIONS_FILE.to_string(), ingestion_ser).unwrap();
} else {
add_ingestion();
}

View file

@ -1,16 +1,15 @@
use crate::config::INGESTIONS_FILE;
use crate::ingestions::{DoseUnit, Ingestion, IngestionMethod};
use crate::{config::INGESTIONS_FILE, substances::Substance};
use chrono::{NaiveDateTime, Utc};
use color_eyre::Section;
use crate::util::path_exists;
use chrono::Utc;
use inquire;
use serde::{self, Deserialize, Serialize};
use std::{collections::HashMap, process::exit};
use strum::{EnumIter, IntoEnumIterator};
use strum::IntoEnumIterator;
use uuid::Uuid;
pub fn ensure_ingestion_files() -> HashMap<Uuid, Ingestion> {
let mut ingesstions_bytes_loaded_des: HashMap<Uuid, Ingestion>;
if crate::substances::path_exists(INGESTIONS_FILE.to_string()) {
let ingesstions_bytes_loaded_des: HashMap<Uuid, Ingestion>;
if path_exists(INGESTIONS_FILE.to_string()) {
let substances_bytes_loaded = std::fs::read(INGESTIONS_FILE.to_string()).unwrap();
ingesstions_bytes_loaded_des = bincode::deserialize(&substances_bytes_loaded).unwrap();
} else {
@ -51,7 +50,7 @@ pub fn get_dose_unit() -> DoseUnit {
}
pub fn get_substance() -> String {
let substances = crate::substances::substances_to_vec();
let substances = crate::substance_util::substances_to_vec();
if substances.is_empty() {
eprintln!("Add a substance before you log an ingestions");
exit(1)

View file

@ -4,9 +4,11 @@ use clap::{Parser, Subcommand};
use config::{INGESTIONS_FILE, LOCAL_PATH, SUBSTANCES_FILE};
mod config;
mod util;
mod ingestions;
mod ingestions_util;
mod substance_util;
mod substances;
#[derive(Parser)]
@ -55,15 +57,15 @@ fn main() {
Some(Commands::ListIngestions) => ingestions::list_ingestions().unwrap(),
Some(Commands::RemoveIngestion) => {}
Some(Commands::AddSubstance) => substances::add_substance().unwrap(),
Some(Commands::EditSubstance) => {}
Some(Commands::EditSubstance) => substances::edit_substance().unwrap(),
Some(Commands::ListSubstances) => substances::list_substances().unwrap(),
Some(Commands::RemoveSubstance) => {}
Some(Commands::RemoveSubstance) => substances::remove_substance().unwrap(),
None => {}
}
}
fn ensure_files() {
if !substances::path_exists(LOCAL_PATH.to_string()) {
if !util::path_exists(LOCAL_PATH.to_string()) {
match std::fs::create_dir(LOCAL_PATH.to_string()) {
Ok(_) => {}
Err(e) => {
@ -72,8 +74,8 @@ fn ensure_files() {
}
}
}
if !substances::path_exists(SUBSTANCES_FILE.to_string()) {
match substances::create_substances_file() {
if !util::path_exists(SUBSTANCES_FILE.to_string()) {
match substance_util::create_substances_file() {
Ok(_) => {
println!(
"Created substances file at {:?}",
@ -86,7 +88,7 @@ fn ensure_files() {
}
};
}
if !substances::path_exists(INGESTIONS_FILE.to_string()) {
if !util::path_exists(INGESTIONS_FILE.to_string()) {
match ingestions::create_ingestions_file() {
Ok(_) => {
println!(

50
src/substance_util.rs Normal file
View file

@ -0,0 +1,50 @@
use std::collections::HashMap;
use uuid::Uuid;
use crate::substances::SubstanceClass;
use crate::util::path_exists;
use crate::{config::SUBSTANCES_FILE, substances::Substance};
pub fn ensure_substance_file() -> HashMap<Uuid, Substance> {
let substances_bytes_loaded_des: HashMap<Uuid, Substance>;
if path_exists(SUBSTANCES_FILE.to_string()) {
let substances_bytes_loaded = std::fs::read(SUBSTANCES_FILE.to_string()).unwrap();
substances_bytes_loaded_des = bincode::deserialize(&substances_bytes_loaded).unwrap();
} else {
std::fs::File::create(SUBSTANCES_FILE.to_string()).unwrap();
substances_bytes_loaded_des = HashMap::new();
}
substances_bytes_loaded_des
}
pub fn get_substance_class(msg: &str, variants: Vec<SubstanceClass>) -> SubstanceClass {
let class = inquire::Select::new(msg, variants).prompt().unwrap();
class
}
pub fn substances_to_vec() -> Vec<String> {
let sub_read_res = std::fs::read(SUBSTANCES_FILE.to_string());
let sub_read = match sub_read_res {
Ok(sub_contents) => sub_contents,
Err(_) => {
println!("Error! Substance file does not exist. Creating file...");
let hash: HashMap<Uuid, Substance> = HashMap::new();
let hash_ser = bincode::serialize(&hash).unwrap();
std::fs::write(SUBSTANCES_FILE.to_string(), hash_ser).unwrap();
let ret: Vec<u8> = vec![];
ret
}
};
let sub_dec: HashMap<Uuid, Substance> = bincode::deserialize(&sub_read).unwrap();
let mut sub_vec: Vec<String> = vec![];
for (_id, substance) in sub_dec.clone().into_iter() {
sub_vec.push(substance.name);
}
sub_vec
}
pub fn create_substances_file() -> Result<(), std::io::Error> {
let hash: HashMap<Uuid, Substance> = HashMap::new();
let hash_ser = bincode::serialize(&hash).unwrap();
std::fs::write(SUBSTANCES_FILE.to_string(), hash_ser)
}

View file

@ -1,18 +1,19 @@
use serde::{self, Deserialize, Serialize};
use std::collections::HashMap;
use strum::{EnumIter, IntoEnumIterator};
use strum::IntoEnumIterator;
use uuid::Uuid;
use crate::config::SUBSTANCES_FILE;
use crate::substance_util::{ensure_substance_file, get_substance_class, substances_to_vec};
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Substance {
name: String,
class: SubstanceClass,
pub name: String,
pub substance_class: SubstanceClass,
}
#[derive(Serialize, Deserialize, Debug, Clone, Copy, strum::Display, strum::EnumIter)]
enum SubstanceClass {
pub enum SubstanceClass {
Stimulant,
Depressant,
Psychedelic,
@ -24,44 +25,18 @@ enum SubstanceClass {
Neurotransmitter,
}
impl SubstanceClass {
fn to_string(&self) -> String {
match self {
Self::Stimulant => "Stimulant".to_string(),
Self::Depressant => "Depressant".to_string(),
Self::Psychedelic => "Psychedelic".to_string(),
Self::Dissociative => "Dissociative".to_string(),
Self::Cannabinoid => "Cannabinoid".to_string(),
Self::Entheogen => "Entheogen".to_string(),
Self::Deliriant => "Deliriant".to_string(),
Self::Empathogen => "Empathogen".to_string(),
Self::Neurotransmitter => "Neurotransmitter".to_string(),
}
}
}
pub fn path_exists(path: String) -> bool {
std::fs::metadata(path).is_ok()
}
pub fn add_substance() -> Result<(), std::io::Error> {
let mut substances_bytes_loaded_des: HashMap<Uuid, Substance>;
if path_exists(SUBSTANCES_FILE.to_string()) {
let substances_bytes_loaded = std::fs::read(SUBSTANCES_FILE.to_string()).unwrap();
substances_bytes_loaded_des = bincode::deserialize(&substances_bytes_loaded).unwrap();
} else {
std::fs::File::create(SUBSTANCES_FILE.to_string()).unwrap();
substances_bytes_loaded_des = HashMap::new();
}
let mut substances_bytes_loaded_des: HashMap<Uuid, Substance> = ensure_substance_file();
let name = inquire::prompt_text("What is the substances name?").unwrap();
if !substances_bytes_loaded_des.values().any(|x| x.name == name) {
let class_variants = SubstanceClass::iter().collect::<Vec<_>>();
let class_select = inquire::Select::new("What type of substance is this?", class_variants)
.prompt()
.unwrap();
let substance_class =
get_substance_class("What type of substance is this?", class_variants);
let substance = Substance {
name,
class: class_select,
substance_class,
};
let subs_hash = substances_bytes_loaded_des.insert(Uuid::new_v4(), substance);
substances_bytes_loaded_des.insert(Uuid::new_v4(), substance);
let sub_enc = bincode::serialize(&substances_bytes_loaded_des).unwrap();
match std::fs::write(SUBSTANCES_FILE.to_string(), sub_enc) {
Ok(_) => Ok(()),
@ -79,36 +54,120 @@ pub fn list_substances() -> Result<(), std::io::Error> {
for (id, substance) in sub_dec.clone().into_iter() {
println!(
"Name: {}\nClass: {:?}\nUUID: {:?}\n",
substance.name, substance.class, id
substance.name, substance.substance_class, id
);
}
Ok(())
}
pub fn substances_to_vec() -> Vec<String> {
let sub_read_res = std::fs::read(SUBSTANCES_FILE.to_string());
let sub_read = match sub_read_res {
Ok(sub_contents) => sub_contents,
Err(_) => {
println!("Error! Substance file does not exist. Creating file...");
let hash: HashMap<Uuid, Substance> = HashMap::new();
let hash_ser = bincode::serialize(&hash).unwrap();
std::fs::write(SUBSTANCES_FILE.to_string(), hash_ser).unwrap();
let ret: Vec<u8> = vec![];
ret
pub fn remove_substance() -> Result<(), std::io::Error> {
let sub_read = std::fs::read(SUBSTANCES_FILE.to_string()).unwrap();
let mut sub_dec: HashMap<Uuid, Substance> = bincode::deserialize(&sub_read).unwrap();
let substances = substances_to_vec();
let substances_select =
inquire::MultiSelect::new("Which substance do you want to remove?", substances)
.prompt()
.unwrap();
dbg!(&substances_select);
for name in substances_select {
let confirm = inquire::prompt_confirmation(format!(
"Are you sure you want to remove '{}'? [y/N]",
name
))
.unwrap();
if confirm {
// Clone to avoid immutable borrow
let sub_dec_clone = sub_dec.clone();
let uuid =
sub_dec_clone
.iter()
.find_map(|(id, val)| if val.name == name { Some(id) } else { None });
if uuid.is_some() {
let _ = sub_dec
.remove(uuid.expect("Fatal error. Couldn't find substance UUID in HashMap."));
}
};
let sub_dec: HashMap<Uuid, Substance> = bincode::deserialize(&sub_read).unwrap();
let mut sub_vec: Vec<String> = vec![];
for (id, substance) in sub_dec.clone().into_iter() {
sub_vec.push(substance.name);
}
sub_vec
}
let sub_enc = bincode::serialize(&sub_dec).unwrap();
match std::fs::write(SUBSTANCES_FILE.to_string(), sub_enc) {
Ok(_) => Ok(()),
Err(e) => Err(e),
}
}
pub fn create_substances_file() -> Result<(), std::io::Error> {
let hash: HashMap<Uuid, Substance> = HashMap::new();
let hash_ser = bincode::serialize(&hash).unwrap();
std::fs::write(SUBSTANCES_FILE.to_string(), hash_ser)
#[derive(Serialize, Deserialize, Debug, Clone, Copy, strum::Display, strum::EnumIter)]
pub enum SubstanceEditOptions {
Name,
Class,
}
pub fn edit_substance() -> Result<(), std::io::Error> {
let sub_read = std::fs::read(SUBSTANCES_FILE.to_string()).unwrap();
let mut sub_dec: HashMap<Uuid, Substance> = bincode::deserialize(&sub_read).unwrap();
let substances = substances_to_vec();
let substance_name = inquire::Select::new("Which substance do you want to edit?", substances)
.prompt()
.unwrap();
dbg!(&substance_name);
let sub_dec_clone = sub_dec.clone();
let uuid_opt = sub_dec_clone.iter().find_map(|(id, val)| {
if val.name == substance_name {
Some(id)
} else {
None
}
});
if uuid_opt.is_some() {
let uuid = uuid_opt.clone().unwrap().to_owned();
let _ = sub_dec
.remove(uuid_opt.expect("Fatal error. Couldn't find substance UUID in HashMap."));
let edit_select = inquire::Select::new(
format!("[{}] What do you want to edit?", substance_name).as_str(),
SubstanceEditOptions::iter().collect::<Vec<_>>(),
)
.prompt()
.unwrap();
match edit_select {
SubstanceEditOptions::Name => {
let name_updated = inquire::prompt_text("What should the new name be?").unwrap();
let class = match sub_dec_clone
.get(uuid_opt.expect("Fatal error. Couldn't find substance UUID in HashMap."))
{
Some(class) => class.substance_class,
None => {
panic!("Fatal error. Couldn't find substance UUID in HashMap.")
}
};
dbg!(&class);
let substance = Substance {
name: name_updated,
substance_class: class,
};
sub_dec.insert(uuid, substance);
}
SubstanceEditOptions::Class => {
let class_variants = SubstanceClass::iter().collect::<Vec<_>>();
let substance_class = get_substance_class(
format!(
"[{}] What should the new substance class be?",
substance_name
)
.as_str(),
class_variants,
);
let substance = Substance {
name: substance_name,
substance_class,
};
sub_dec.insert(uuid, substance);
}
}
let sub_enc = bincode::serialize(&sub_dec).unwrap();
std::fs::write(SUBSTANCES_FILE.to_string(), sub_enc).unwrap();
}
Ok(())
}

3
src/util.rs Normal file
View file

@ -0,0 +1,3 @@
pub fn path_exists(path: String) -> bool {
std::fs::metadata(path).is_ok()
}