main.rs (4274B)
1#![feature(get_mut_unchecked)] 2 3use std::collections::BTreeMap; 4use std::io::{self, Read, Stdin, Stdout, Write}; 5use std::iter::RepeatN; 6use std::rc::Rc; 7 8struct InputHelper { 9 stdin: Stdin, 10 stdout: Stdout, 11 buf: Vec<u8>, 12} 13 14impl InputHelper { 15 fn with_capacity(cap: usize) -> Self { 16 let stdin = io::stdin(); 17 let stdout = io::stdout(); 18 Self { 19 stdin, 20 stdout, 21 buf: vec![0u8; cap], 22 } 23 } 24 25 fn ask(&mut self, msg: &str) -> &[u8] { 26 self.stdout.write(msg.as_bytes()).unwrap(); 27 self.stdout.write(b"\n").unwrap(); 28 let len = self.stdin.read(&mut self.buf).unwrap(); 29 &self.buf[..len].trim_ascii() 30 } 31 32 fn ask_num(&mut self, msg: &str) -> i64 { 33 let buf = self.ask(msg); 34 std::str::from_utf8(buf).unwrap().parse().unwrap() 35 } 36} 37 38#[derive(Debug)] 39struct Exercise { 40 name: Vec<u8>, 41 description: Vec<u8>, 42} 43 44#[derive(Debug, Clone)] 45struct Workout { 46 exercises: Vec<RepeatN<Rc<Exercise>>>, 47} 48 49fn main() { 50 let mut exercises = BTreeMap::new(); 51 let mut workouts = Vec::new(); 52 53 let mut input = InputHelper::with_capacity(0x100); 54 55 println!("Welcome to your personal training helper! Here are your options:"); 56 loop { 57 println!("1. : add a new exercise to your portfolio"); 58 println!("2. : plan a new workout"); 59 println!("3. : start a training session"); 60 println!("4. : edit an exercise"); 61 println!("5. : exit the app"); 62 63 let line = input.ask("Choose an option: ").trim_ascii(); 64 match &*line { 65 b"1" => { 66 let name = input.ask("What's the name of your exercise? ").to_owned(); 67 68 let description = input 69 .ask("what is the description of your exercise? ") 70 .to_owned(); 71 72 let name2 = name.clone(); 73 let exercise: Exercise = Exercise { name, description }; 74 exercises.insert(name2, Rc::new(exercise)); 75 println!("Exercise added!"); 76 } 77 b"2" => { 78 let num_exercises = input.ask_num("How many exercises should your workout have? "); 79 let mut workout = Workout { 80 exercises: Vec::new(), 81 }; 82 83 for _ in 0..num_exercises { 84 let name = input.ask("Enter the name of the exercise: "); 85 if let Some(exercise) = exercises.get(name) { 86 let num_repetitions = 87 input.ask_num("How many times should your exercise be repeated? "); 88 workout.exercises.push(std::iter::repeat_n( 89 Rc::clone(exercise), 90 num_repetitions as usize, 91 )); 92 } else { 93 println!("No exercise found with that name."); 94 } 95 } 96 97 println!("Your workout has id {}", workouts.len()); 98 workouts.push(workout); 99 } 100 b"3" => { 101 let id = input.ask_num("what's the id of your workout? "); 102 103 let workout = &workouts[id as usize]; 104 105 for exercise in workout.exercises.iter().cloned() { 106 for ex in exercise { 107 println!("{:?} - {:?}", ex.name, ex.description); // pls help, this looks weird :( 108 } 109 } 110 } 111 b"4" => { 112 let name = input.ask("Enter the name of the exercise you want to edit: "); 113 if let Some(exercise) = exercises.get_mut(name) { 114 let description = input.ask("Enter the new description: "); 115 unsafe { 116 Rc::get_mut_unchecked(exercise) 117 .description 118 .copy_from_slice(description) 119 } 120 println!("Exercise updated!"); 121 } else { 122 println!("No exercise found with that name."); 123 } 124 } 125 b"5" => break, 126 _ => println!("That was not a valid option"), 127 } 128 } 129}