From 398a9c94c562fe7c20154886f0bfebbf4f239025 Mon Sep 17 00:00:00 2001 From: DSiekmeier Date: Tue, 7 Nov 2023 13:19:37 +0100 Subject: [PATCH] feature: add edit subcommand (#20) --- README.md | 4 ++++ src/book.h | 17 ++++++++++++++++- src/cli.cc | 12 ++++++++++++ src/cli.h | 10 ++++++++++ src/main.cc | 29 +++++++++++++++++++++++++++++ 5 files changed, 71 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index dec6303..329c7d7 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,9 @@ Here is a short introduction how to use **booktrack-cli**. # Delete a book from the given library by the book id ./booktrack-cli -l ~/my_lib.json delete --by-id 2 + +# Edit the title of the book from the given library with the book id 4 +./booktrack-cli -l ~/my_lib.json edit --by-id 4 --title "Introduction to Algorithms" ``` You can see a full list of commandline options below. @@ -59,6 +62,7 @@ Subcommands: list List books in the library statistics Show statistics for loaded library details Show details for a book + edit Edit a book in the library ``` ## Notes diff --git a/src/book.h b/src/book.h index 62bde7c..a160d7b 100644 --- a/src/book.h +++ b/src/book.h @@ -40,11 +40,21 @@ class Book { */ inline auto GetTitle() const { return title_; }; + /** + * @brief Set the title of the current book + */ + inline auto SetTitle(const std::string& title) { title_ = title; } + /** * @brief Get the author of the current book */ inline auto GetAuthor() const { return author_; } + /** + * @brief Set the author of the current book + */ + inline auto SetAuthor(const std::string& author) { author_ = author; } + /** * @brief Get the reading end time of the current book */ @@ -60,6 +70,11 @@ class Book { */ inline auto GetPages() const { return pages_; } + /** + * @brief Set the number of pages of the current book + */ + inline auto SetPages(unsigned int pages) { pages_ = pages; } + /** * @brief Get the shelf to which the current book belongs to */ @@ -86,7 +101,7 @@ class Book { /** * @brief Sets all information of a Book instance from a JSON object - * + * * @throws std::exception subclass on error */ void SetDataFromJson(const nlohmann::json& book_json); diff --git a/src/cli.cc b/src/cli.cc index 407c9d4..f0b67d2 100644 --- a/src/cli.cc +++ b/src/cli.cc @@ -91,6 +91,17 @@ void AddDetailsOptions(CLI::App& app, CliOptions& opt) { sub_details->add_option("--by-id", opt.details.id, "")->mandatory(); } +void AddEditOptions(CLI::App& app, CliOptions& opt) { + auto sub_edit = + app.add_subcommand("edit", "Edit a book in the library") + ->callback([&opt]() { opt.command = PrimaryCommand::kEdit; }); + + sub_edit->add_option("--by-id", opt.edit.id, "")->mandatory(); + sub_edit->add_option("-t,--title", opt.edit.changeset.title, ""); + sub_edit->add_option("-a,--author", opt.edit.changeset.author, ""); + sub_edit->add_option("-p,--pages", opt.edit.changeset.pages, ""); +} + } // namespace void booktrack_cli::AddCliOptions(CLI::App& app, CliOptions& opt) { @@ -100,4 +111,5 @@ void booktrack_cli::AddCliOptions(CLI::App& app, CliOptions& opt) { AddListOptions(app, opt); AddStatisticsOptions(app, opt); AddDetailsOptions(app, opt); + AddEditOptions(app, opt); } diff --git a/src/cli.h b/src/cli.h index de93255..4dade7e 100644 --- a/src/cli.h +++ b/src/cli.h @@ -16,6 +16,7 @@ enum class PrimaryCommand { kDelete, kStatistics, kDetails, + kEdit, }; /** @@ -59,6 +60,14 @@ struct CliOptionsDetails { size_t id{0}; }; +/** + * @brief Contains available options for the "edit" subcommand + */ +struct CliOptionsEdit { + size_t id{0}; + CliOptionsAdd changeset; +}; + /** * @brief Structure containing all options for the command line interface */ @@ -70,6 +79,7 @@ struct CliOptions { CliOptionsList list; CliOptionsStatistics statistics; CliOptionsDetails details; + CliOptionsEdit edit; }; /** diff --git a/src/main.cc b/src/main.cc index 68c6a2f..6db2046 100644 --- a/src/main.cc +++ b/src/main.cc @@ -93,6 +93,32 @@ void SubcmdDetails(Library& lib, const CliOptionsDetails& options) { } } +void SubcmdEdit(Library& lib, [[maybe_unused]] const CliOptionsEdit& options) { + auto check_exist = lib.GetBookById(options.id); + + if (check_exist.has_value()) { + auto book = check_exist.value(); + auto changes = options.changeset; + + // update book + if (!changes.title.empty()) { + book.SetTitle(changes.title); + } + + if (!changes.author.empty()) { + book.SetAuthor(changes.author); + } + + book.SetPages(changes.pages); + + // Update library + lib.RemoveBookById(book.GetId()); + lib.AddBook(book).StoreToFile(); + } else { + std::cout << "Could not find a book with id: " << options.id << ".\n"; + } +} + } // namespace int main(int argc, char* argv[]) { @@ -120,6 +146,9 @@ int main(int argc, char* argv[]) { case PrimaryCommand::kDetails: SubcmdDetails(library_from_file, options.details); break; + case PrimaryCommand::kEdit: + SubcmdEdit(library_from_file, options.edit); + break; default: break; }