From 463e4260b377ceeecc994424955a4fc30573745c Mon Sep 17 00:00:00 2001 From: "Dustin J. Mitchell" Date: Sun, 13 Oct 2024 13:20:12 -0400 Subject: [PATCH] Support more comprehensive checks when adding a task --- src/TDB2.cpp | 4 ++++ src/Task.cpp | 18 ++++++++++++++++-- src/Task.h | 1 + 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/TDB2.cpp b/src/TDB2.cpp index 2240c5213..d5dacd769 100644 --- a/src/TDB2.cpp +++ b/src/TDB2.cpp @@ -57,6 +57,10 @@ void TDB2::open_replica(const std::string& location, bool create_if_missing) { //////////////////////////////////////////////////////////////////////////////// // Add the new task to the replica. void TDB2::add(Task& task) { + // Validate a task for addition. This is stricter than `task.validate`, as any + // inconsistency is probably user error. + task.validate_add(); + // Ensure the task is consistent, and provide defaults if necessary. // bool argument to validate() is "applyDefault", to apply default values for // properties not otherwise given. diff --git a/src/Task.cpp b/src/Task.cpp index df06addf0..6c51dedbe 100644 --- a/src/Task.cpp +++ b/src/Task.cpp @@ -1408,6 +1408,21 @@ void Task::substitute(const std::string& from, const std::string& to, const std: } #endif +//////////////////////////////////////////////////////////////////////////////// +// Validate a task for addition, raising user-visible errors for inconsistent or +// incorrect inputs. This is called before `Task::validate`. +void Task::validate_add() { + // There is no fixing a missing description. + if (!has("description")) + throw std::string("A task must have a description."); + else if (get("description") == "") + throw std::string("Cannot add a task that is blank."); + + // Cannot have an old-style recur frequency with no due date - when would it recur? + if (has("recur") && (!has("due") || get("due") == "")) + throw std::string("A recurring task must also have a 'due' date."); +} + //////////////////////////////////////////////////////////////////////////////// // The purpose of Task::validate is three-fold: // 1) To provide missing attributes where possible @@ -1431,8 +1446,7 @@ void Task::validate(bool applyDefault /* = true */) { Lexer::Type type; // `uuid` is not a property in the TaskChampion model, so an invalid UUID is // actually an error. - if (!lex.isUUID(token, type, true)) - throw format("Not a valid UUID '{1}'.", uid); + if (!lex.isUUID(token, type, true)) throw format("Not a valid UUID '{1}'.", uid); } else set("uuid", uuid()); diff --git a/src/Task.h b/src/Task.h index 08d508f0a..f36e79b83 100644 --- a/src/Task.h +++ b/src/Task.h @@ -164,6 +164,7 @@ class Task { void substitute(const std::string&, const std::string&, const std::string&); #endif + void validate_add(); void validate(bool applyDefault = true); float urgency_c() const;