173 lines
5.0 KiB
C++
173 lines
5.0 KiB
C++
#include "Patient.hpp"
|
|
#include <algorithm>
|
|
#include <fstream>
|
|
#include <functional>
|
|
#include <iostream>
|
|
#include <optional>
|
|
#include <sstream>
|
|
#include <sys/types.h>
|
|
|
|
#ifndef CLINIC_
|
|
#define CLINIC_
|
|
|
|
enum class MenuChoice {
|
|
NewPatient = 1,
|
|
NewVisit = 2,
|
|
DisplayPatient = 3,
|
|
Quit = 4,
|
|
};
|
|
|
|
struct Clinic {
|
|
public:
|
|
std::vector<Patient> patients;
|
|
std::string filename;
|
|
|
|
private:
|
|
// C++ types are getting crazy here :( I really miss Rust
|
|
// `std::optional` needed because a patient might not be found
|
|
// `std::reference_wrapper` because `std::optional` deoesn't accept references
|
|
// I want to reference because (I want to save cpu cycles from memory copies)
|
|
std::optional<std::reference_wrapper<Patient>>
|
|
find_patient(u_int32_t patient_id) {
|
|
auto it = std::find_if(patients.begin(), patients.end(),
|
|
[&id = patient_id](const Patient &p) -> bool {
|
|
return p.get_id() == id;
|
|
});
|
|
if (it != patients.end())
|
|
return *it;
|
|
return std::nullopt;
|
|
};
|
|
|
|
public:
|
|
Clinic(std::string filename) : filename(filename) {
|
|
/// this file contains a list of patient IDs.
|
|
// 1
|
|
// 2
|
|
// 4 (could be non-sequential
|
|
// but always sorted!)
|
|
u_int32_t patient_id;
|
|
std::ifstream file{filename};
|
|
if (!file.is_open()) {
|
|
std::cerr << "File " << filename << " couldn't be opened :(\n";
|
|
exit(1);
|
|
}
|
|
|
|
while (file >> patient_id)
|
|
patients.push_back(Patient(patient_id));
|
|
}
|
|
|
|
// writes the patients.txt file containing patient IDs.
|
|
void write_file() {
|
|
std::ofstream file{filename};
|
|
for (auto p : patients)
|
|
file << p.get_id() << "\n";
|
|
}
|
|
u_int32_t generate_id() {
|
|
u_int32_t id{};
|
|
// O(n), could be improved by using UUIDs, or store max_id in Clinic
|
|
for (auto p : patients)
|
|
id = std::max(id, p.get_id());
|
|
id++;
|
|
return id;
|
|
}
|
|
|
|
MenuChoice menu_main() {
|
|
int choice{};
|
|
std::cout << "==============================================\n";
|
|
std::cout << "Please choose a command:\n";
|
|
std::cout << "1. add new patient\n";
|
|
std::cout << "2. add new visit\n";
|
|
std::cout << "3. display patient information\n";
|
|
std::cout << "4. quit\n";
|
|
std::cout << ">> ";
|
|
|
|
std::cin >> choice;
|
|
|
|
while (choice < int(MenuChoice::NewPatient) ||
|
|
choice > int(MenuChoice::Quit)) {
|
|
std::cout << "Invalid input! Try again :)\n";
|
|
std::cout << "Please choose a command:\n";
|
|
std::cout << "1. add new patient\n";
|
|
std::cout << "2. add new visit\n";
|
|
std::cout << "3. display patient information\n";
|
|
std::cout << "4. quit\n";
|
|
std::cout << ">> ";
|
|
std::cin >> choice;
|
|
}
|
|
return static_cast<MenuChoice>(choice);
|
|
}
|
|
|
|
void menu_patient_info() {
|
|
int patient_id;
|
|
std::cout << "Patient file number: ";
|
|
std::cin >> patient_id;
|
|
auto patient = find_patient(patient_id);
|
|
if (patient.has_value())
|
|
std::cout << patient.value();
|
|
else
|
|
std::cout << "No Patient exists with id= " << patient_id << "\n";
|
|
std::cout << "--------------------\n\n";
|
|
}
|
|
|
|
void menu_add_new_patient() {
|
|
std::string reading_string;
|
|
std::string input_string;
|
|
Patient patient{};
|
|
std::stringstream patient_stream;
|
|
|
|
// not the most optimal way, but the lazy way
|
|
// see: https://ammar.engineer/posts/2023/06/03/laziness/
|
|
// this "emulates" a file so that I can resuse my >> operator
|
|
reading_string += std::to_string(generate_id()) + "\n";
|
|
std::cout << "Generate " << reading_string;
|
|
std::cout << "First name (no spaces): ";
|
|
std::cin >> input_string;
|
|
reading_string += input_string + "\n";
|
|
std::cout << "Last name (no spaces): ";
|
|
std::cin >> input_string;
|
|
reading_string += input_string + "\n";
|
|
std::cout << "Gender (M or F): ";
|
|
std::cin >> input_string;
|
|
reading_string += input_string + "\n";
|
|
std::cout << "Age: ";
|
|
std::cin >> input_string;
|
|
reading_string += input_string + "\n";
|
|
std::cout << reading_string;
|
|
patient_stream = std::stringstream(reading_string);
|
|
|
|
// all of that just for this moment:
|
|
patient_stream >> patient;
|
|
patients.push_back(patient); // save in memory
|
|
patient.write_patient(); // write to file
|
|
write_file();
|
|
}
|
|
void menu_add_vist() {
|
|
std::string reading_string;
|
|
std::string input_string;
|
|
int patient_id;
|
|
|
|
std::cout << "Patient file number: ";
|
|
std::cin >> patient_id;
|
|
std::cout << "Date:";
|
|
std::cin >> input_string;
|
|
reading_string += input_string + " ";
|
|
std::cout << "Doctor's First Name: ";
|
|
std::cin >> input_string;
|
|
reading_string += input_string + " ";
|
|
std::cout << "Doctors's Last Name: ";
|
|
std::cin >> input_string;
|
|
reading_string += input_string + " ";
|
|
|
|
std::stringstream visit_stream = std::stringstream(reading_string);
|
|
Visit visit;
|
|
visit_stream >> visit;
|
|
auto patient = find_patient(patient_id);
|
|
if (patient.has_value())
|
|
patient.value().get().add_visit(visit);
|
|
else
|
|
std::cout << "No Patient exists with id= " << patient_id << "\n";
|
|
}
|
|
};
|
|
|
|
#endif
|