summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDirk-Jan C. Binnema <djcb@djcbsoftware.nl>2024-11-30 22:58:15 +0200
committerDirk-Jan C. Binnema <djcb@djcbsoftware.nl>2024-11-30 22:58:15 +0200
commit8c7db599727f42bf381fb4b636b462a82256dcf8 (patch)
tree62cef6cea14cc5fc61b8bd3d68f27e3f0e64b3ab /lib
parent0200cfd647e02334a03805a6432e81b98983d6b9 (diff)
fields: make combi-fields introspectable
And add the display of combination-fields to 'mu info fields'.
Diffstat (limited to 'lib')
-rw-r--r--lib/message/mu-fields.cc50
-rw-r--r--lib/message/mu-fields.hh71
2 files changed, 78 insertions, 43 deletions
diff --git a/lib/message/mu-fields.cc b/lib/message/mu-fields.cc
index f64df5f..57399b5 100644
--- a/lib/message/mu-fields.cc
+++ b/lib/message/mu-fields.cc
@@ -1,5 +1,5 @@
/*
-** Copyright (C) 2022-2023 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
+** Copyright (C) 2022-2024 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** This program is free software; you can redistribute it and/or modify it
** under the terms of the GNU General Public License as published by the
@@ -19,11 +19,59 @@
#include "mu-fields.hh"
#include "mu-flags.hh"
+#include "utils/mu-utils.hh"
#include "utils/mu-test-utils.hh"
using namespace Mu;
+const Mu::CombiFields&
+Mu::combi_fields()
+{
+ static CombiFields cfields = {
+ CombiField{ "recip",
+ { field_from_id(Field::Id::To),
+ field_from_id(Field::Id::Cc),
+ field_from_id(Field::Id::Bcc)}},
+ CombiField { "contact",
+ { field_from_id(Field::Id::To),
+ field_from_id(Field::Id::Cc),
+ field_from_id(Field::Id::Bcc),
+ field_from_id(Field::Id::From)}},
+ CombiField { "",
+ { field_from_id(Field::Id::To),
+ field_from_id(Field::Id::Cc),
+ field_from_id(Field::Id::Bcc),
+ field_from_id(Field::Id::From),
+ field_from_id(Field::Id::Subject),
+ field_from_id(Field::Id::BodyText),
+ field_from_id(Field::Id::EmbeddedText),
+ }}
+ };
+
+ return cfields;
+}
+
+const Mu::FieldsVec&
+Mu::fields_from_name(const std::string& name) {
+
+ static const FieldsVec empty;
+ const auto& cfields{combi_fields()};
+ const auto it = seq_find_if(cfields, [&](auto cfield) {
+ return cfield.name == name;
+ });
+
+ return it == cfields.end() ? empty : it->fields;
+}
+
+bool
+Mu::field_is_combi(const std::string& name)
+{
+ return name != "" && seq_some(combi_fields(),[&](auto cfield) {
+ return cfield.name == name;
+ });
+}
+
std::string
Field::xapian_term(const std::string& s) const
{
diff --git a/lib/message/mu-fields.hh b/lib/message/mu-fields.hh
index 63838aa..afa4036 100644
--- a/lib/message/mu-fields.hh
+++ b/lib/message/mu-fields.hh
@@ -402,7 +402,7 @@ static constexpr std::array<Field, Field::id_size()>
{},
'r',
Field::Flag::Value |
- Field::Flag::BooleanTerm |
+ Field::Flag::BooleanTerm |
Field::Flag::IncludeInSexp
},
{
@@ -534,6 +534,25 @@ Option<Field> field_from_name(const std::string& name) {
}
}
+using FieldsVec = std::vector<Field>; /**< Vec of fields */
+
+/**
+ * Describe a combination-field, i.e., a pseudo-field that
+ * expands to some real fields, as a query shortcut.
+ */
+struct CombiField {
+ std::string_view name; /**< name of the combi-field */
+ FieldsVec fields; /**< fields this resolves to */
+};
+using CombiFields = std::vector<CombiField>; /**< vec of combi-fields */
+
+/**
+ * Get information about the combination fields
+ *
+ * @return vector with information.
+ */
+const CombiFields& combi_fields();
+
/**
* Return combination-fields such
* as "contact", "recip" and "" (empty)
@@ -542,48 +561,16 @@ Option<Field> field_from_name(const std::string& name) {
*
* @return list of matching fields
*/
-using FieldsVec = std::vector<Field>;
-static inline
-const FieldsVec& fields_from_name(const std::string& name) {
-
- static const FieldsVec none{};
- static const FieldsVec recip_fields ={
- field_from_id(Field::Id::To),
- field_from_id(Field::Id::Cc),
- field_from_id(Field::Id::Bcc)};
-
- static const FieldsVec contact_fields = {
- field_from_id(Field::Id::To),
- field_from_id(Field::Id::Cc),
- field_from_id(Field::Id::Bcc),
- field_from_id(Field::Id::From),
- };
- static const FieldsVec empty_fields= {
- field_from_id(Field::Id::To),
- field_from_id(Field::Id::Cc),
- field_from_id(Field::Id::Bcc),
- field_from_id(Field::Id::From),
- field_from_id(Field::Id::Subject),
- field_from_id(Field::Id::BodyText),
- field_from_id(Field::Id::EmbeddedText),
- };
-
- if (name == "recip")
- return recip_fields;
- else if (name == "contact")
- return contact_fields;
- else if (name.empty())
- return empty_fields;
- else
- return none;
-}
-
-static inline bool
-field_is_combi (const std::string& name)
-{
- return name == "recip" || name == "contact";
-}
+const FieldsVec& fields_from_name(const std::string& name);
+/**
+ * Is the field a combination field?
+ *
+ * @param name name of the field
+ *
+ * @return true or false
+ */
+bool field_is_combi (const std::string& name);
/**
* Get the Field::Id for some number, or nullopt if it does not match