Add Task.is_empty, needed to identify "dummy" tasks (simple refactor)

getDOM takes an &Task that may be a reference to a dummy, or may be a
real task.  The is_empty method replaces `task.data.size() == 0` as a
way to distinguish the two.
This commit is contained in:
Dustin J. Mitchell 2021-11-18 02:17:24 +00:00 committed by Tomas Babej
parent dede40bc4e
commit 0d9e402d3e
3 changed files with 24 additions and 11 deletions

View file

@ -245,14 +245,16 @@ bool getDOM (const std::string& name, const Task& task, Variant& value)
if (name == "") if (name == "")
return false; return false;
auto have_task = !task.is_empty();
// Quickly deal with the most common cases. // Quickly deal with the most common cases.
if (task.data_removeme ().size () && name == "id") if (have_task && name == "id")
{ {
value = Variant (static_cast<int> (task.id)); value = Variant (static_cast<int> (task.id));
return true; return true;
} }
if (task.data_removeme ().size () && name == "urgency") if (have_task && name == "urgency")
{ {
value = Variant (task.urgency_c ()); value = Variant (task.urgency_c ());
return true; return true;
@ -310,6 +312,7 @@ bool getDOM (const std::string& name, const Task& task, Variant& value)
return task; return task;
} (); } ();
auto have_ref = !ref.is_empty();
auto size = elements.size (); auto size = elements.size ();
@ -318,13 +321,13 @@ bool getDOM (const std::string& name, const Task& task, Variant& value)
{ {
// Now that 'ref' is the contextual task, and any ID/UUID is chopped off the // Now that 'ref' is the contextual task, and any ID/UUID is chopped off the
// elements vector, DOM resolution is now simple. // elements vector, DOM resolution is now simple.
if (ref.data_removeme ().size () && size == 1 && canonical == "id") if (have_ref && size == 1 && canonical == "id")
{ {
value = Variant (static_cast<int> (ref.id)); value = Variant (static_cast<int> (ref.id));
return true; return true;
} }
if (ref.data_removeme ().size () && size == 1 && canonical == "urgency") if (have_ref && size == 1 && canonical == "urgency")
{ {
value = Variant (ref.urgency_c ()); value = Variant (ref.urgency_c ());
return true; return true;
@ -332,7 +335,7 @@ bool getDOM (const std::string& name, const Task& task, Variant& value)
// Special handling of status required for virtual waiting status // Special handling of status required for virtual waiting status
// implementation. Remove in 3.0.0. // implementation. Remove in 3.0.0.
if (ref.data_removeme ().size () && size == 1 && canonical == "status") if (have_ref && size == 1 && canonical == "status")
{ {
value = Variant (ref.statusToText (ref.getStatus ())); value = Variant (ref.statusToText (ref.getStatus ()));
return true; return true;
@ -340,7 +343,7 @@ bool getDOM (const std::string& name, const Task& task, Variant& value)
Column* column = Context::getContext ().columns[canonical]; Column* column = Context::getContext ().columns[canonical];
if (ref.data_removeme ().size () && size == 1 && column) if (have_ref && size == 1 && column)
{ {
if (column->is_uda () && ! ref.has (canonical)) if (column->is_uda () && ! ref.has (canonical))
{ {
@ -375,13 +378,13 @@ bool getDOM (const std::string& name, const Task& task, Variant& value)
return true; return true;
} }
if (ref.data_removeme ().size () && size == 2 && canonical == "tags") if (have_ref && size == 2 && canonical == "tags")
{ {
value = Variant (ref.hasTag (elements[1]) ? elements[1] : ""); value = Variant (ref.hasTag (elements[1]) ? elements[1] : "");
return true; return true;
} }
if (ref.data_removeme ().size () && size == 2 && column && column->type () == "date") if (have_ref && size == 2 && column && column->type () == "date")
{ {
Datetime date (ref.get_date (canonical)); Datetime date (ref.get_date (canonical));
if (elements[1] == "year") { value = Variant (static_cast<int> (date.year ())); return true; } if (elements[1] == "year") { value = Variant (static_cast<int> (date.year ())); return true; }
@ -396,13 +399,13 @@ bool getDOM (const std::string& name, const Task& task, Variant& value)
} }
} }
if (ref.data_removeme ().size () && size == 2 && elements[0] == "annotations" && elements[1] == "count") if (have_ref && size == 2 && elements[0] == "annotations" && elements[1] == "count")
{ {
value = Variant (static_cast<int> (ref.getAnnotationCount ())); value = Variant (static_cast<int> (ref.getAnnotationCount ()));
return true; return true;
} }
if (ref.data_removeme ().size () && size == 3 && elements[0] == "annotations") if (have_ref && size == 3 && elements[0] == "annotations")
{ {
auto annos = ref.getAnnotations (); auto annos = ref.getAnnotations ();
@ -430,7 +433,7 @@ bool getDOM (const std::string& name, const Task& task, Variant& value)
} }
} }
if (ref.data_removeme ().size () && size == 4 && elements[0] == "annotations" && elements[2] == "entry") if (have_ref && size == 4 && elements[0] == "annotations" && elements[2] == "entry")
{ {
auto annos = ref.getAnnotations (); auto annos = ref.getAnnotations ();

View file

@ -363,6 +363,14 @@ Task::dateState Task::getDateState (const std::string& name) const
return dateNotDue; return dateNotDue;
} }
////////////////////////////////////////////////////////////////////////////////
// An empty task is typically a "dummy", such as in DOM evaluation, which may or
// may not occur in the context of a task.
bool Task::is_empty () const
{
return data.size () == 0;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Ready means pending, not blocked and either not scheduled or scheduled before // Ready means pending, not blocked and either not scheduled or scheduled before
// now. // now.

View file

@ -100,6 +100,8 @@ public:
void set (const std::string&, long long); void set (const std::string&, long long);
void remove (const std::string&); void remove (const std::string&);
bool is_empty () const;
#ifdef PRODUCT_TASKWARRIOR #ifdef PRODUCT_TASKWARRIOR
bool is_ready () const; bool is_ready () const;
bool is_due () const; bool is_due () const;