From 5f8ec9bbe0da50b4c5e5a56e3612b35de32123d0 Mon Sep 17 00:00:00 2001 From: Tomas Babej Date: Tue, 28 Sep 2021 00:52:56 -0400 Subject: [PATCH] CmdConfig: Extract write context validation into a separate method --- src/commands/CmdContext.cpp | 63 +++++++++++++++++++++---------------- src/commands/CmdContext.h | 2 ++ 2 files changed, 38 insertions(+), 27 deletions(-) diff --git a/src/commands/CmdContext.cpp b/src/commands/CmdContext.cpp index d0f044c6a..d41a9a1dd 100644 --- a/src/commands/CmdContext.cpp +++ b/src/commands/CmdContext.cpp @@ -106,6 +106,39 @@ std::string CmdContext::joinWords (const std::vector & words, unsig return value; } +//////////////////////////////////////////////////////////////////////////////// +// Validate the context as valid for writing and fail the write context definition +// A valid write context: +// - does not contain any operators except AND +// - does not use modifiers +// +// Returns True if the context is a valid write context. If the context is +// invalid due to a wrong modifier use, the modifier string will contain the +// first invalid modifier. +bool CmdContext::validateWriteContext (const std::vector & lexedArgs, std::string& modifier_token) +{ + bool contains_or = false; + bool contains_modifier = false; + + for (auto &arg: lexedArgs) { + if (arg._lextype == Lexer::Type::op) + if (arg.attribute ("raw") == "or") + contains_or = true; + + if (arg._lextype == Lexer::Type::pair) { + auto modifier = arg.attribute ("modifier"); + if (modifier != "" && modifier != "is" && modifier != "equals") + { + contains_modifier = true; + modifier_token = arg.attribute ("raw"); + break; + } + } + } + + return not contains_or and not contains_modifier; +} + //////////////////////////////////////////////////////////////////////////////// // Returns all user defined contexts. // @@ -177,38 +210,14 @@ void CmdContext::defineContext (const std::vector & words, std::str ! confirm (format ("The filter '{1}' matches 0 pending tasks. Do you wish to continue?", value))) throw std::string ("Context definition aborted."); - // Validate the context as valid for writing and fail the write context definition - // A valid write context: - // - does not contain any operators except AND - // - does not use modifiers - bool contains_or = false; - bool contains_modifier = false; - std::string modifier_token; - - for (auto &arg: lexedArgs) { - if (arg._lextype == Lexer::Type::op) - if (arg.attribute ("raw") == "or") - contains_or = true; - - if (arg._lextype == Lexer::Type::pair) { - auto modifier = arg.attribute ("modifier"); - if (modifier != "" && modifier != "is" && modifier != "equals") - { - contains_modifier = true; - modifier_token = arg.attribute ("raw"); - out << "The modifier value is '" << modifier << "'.\n"; - break; - } - } - } - - bool valid_write_context = not contains_or and not contains_modifier; + std::string modifier_token = ""; + bool valid_write_context = CmdContext::validateWriteContext (lexedArgs, modifier_token); if (! valid_write_context) { std::stringstream warning; warning << format ("The filter '{1}' is not a valid modification string, because it contains ", value) - << ( contains_or ? "the OR operator." : format ("an attribute modifier ({1}).", modifier_token) ) + << ( modifier_token.empty () ? "the OR operator." : format ("an attribute modifier ({1}).", modifier_token) ) << "\nAs such, value for the write context cannot be set (context will not apply on task add / task log).\n\n" << format ("Please use 'task config context.{1}.write ' to set default attribute values for new tasks in this context manually.\n\n", words[1]); out << colorizeFootnote (warning.str ()); diff --git a/src/commands/CmdContext.h b/src/commands/CmdContext.h index 08a12249a..c21e8a0b3 100644 --- a/src/commands/CmdContext.h +++ b/src/commands/CmdContext.h @@ -29,6 +29,7 @@ #include #include +#include class CmdContext : public Command { @@ -36,6 +37,7 @@ public: CmdContext (); int execute (std::string&); std::string joinWords (const std::vector &, unsigned int, unsigned int = 0); + bool validateWriteContext (const std::vector &, std::string&); static std::vector getContexts (); void defineContext (const std::vector &, std::stringstream&); void deleteContext (const std::vector &, std::stringstream&);