2022-02-23 08:29:37 +01:00
|
|
|
/*
|
|
|
|
** Copyright (C) 2022 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
|
|
|
|
** Free Software Foundation; either version 3, or (at your option) any
|
|
|
|
** later version.
|
|
|
|
**
|
|
|
|
** This program is distributed in the hope that it will be useful,
|
|
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
** GNU General Public License for more details.
|
|
|
|
**
|
|
|
|
** You should have received a copy of the GNU General Public License
|
|
|
|
** along with this program; if not, write to the Free Software Foundation,
|
|
|
|
** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
|
2022-03-19 17:56:10 +01:00
|
|
|
#ifndef MU_FIELDS_HH__
|
|
|
|
#define MU_FIELDS_HH__
|
2022-02-23 08:29:37 +01:00
|
|
|
|
|
|
|
#include <cstdint>
|
|
|
|
#include <string_view>
|
|
|
|
#include <algorithm>
|
|
|
|
#include <array>
|
|
|
|
#include <xapian.h>
|
|
|
|
#include <utils/mu-utils.hh>
|
2022-03-26 15:19:08 +01:00
|
|
|
#include <utils/mu-option.hh>
|
2022-02-23 08:29:37 +01:00
|
|
|
|
|
|
|
namespace Mu {
|
|
|
|
|
2022-03-19 17:56:10 +01:00
|
|
|
struct Field {
|
2022-02-23 08:29:37 +01:00
|
|
|
/**
|
|
|
|
* Field Ids.
|
|
|
|
*
|
2022-03-19 17:56:10 +01:00
|
|
|
* Note, the Ids are also used as indices in the Fields array,
|
2022-02-23 08:29:37 +01:00
|
|
|
* so their numerical values must be 0...Count.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
enum struct Id {
|
|
|
|
/*
|
|
|
|
* first all the string-based ones
|
|
|
|
*/
|
|
|
|
Bcc = 0, /**< Blind Carbon-Copy */
|
|
|
|
BodyHtml, /**< HTML Body */
|
|
|
|
BodyText, /**< Text body */
|
|
|
|
Cc, /**< Carbon-Copy */
|
|
|
|
EmbeddedText, /**< Embedded text in message */
|
|
|
|
File, /**< Filename */
|
|
|
|
From, /**< Message sender */
|
|
|
|
Maildir, /**< Maildir path */
|
|
|
|
Mime, /**< MIME-Type */
|
|
|
|
MessageId, /**< Message Id */
|
|
|
|
Path, /**< File-system Path */
|
|
|
|
Subject, /**< Message subject */
|
|
|
|
To, /**< To: recipient */
|
2022-03-19 17:56:10 +01:00
|
|
|
Uid, /**< Unique id for message (based on path) */
|
2022-02-23 08:29:37 +01:00
|
|
|
/*
|
|
|
|
* string list items...
|
|
|
|
*/
|
|
|
|
References, /**< All references (incl. Reply-To:) */
|
|
|
|
Tags, /**< Message Tags */
|
|
|
|
/*
|
|
|
|
* then the numerical ones
|
|
|
|
*/
|
|
|
|
Date, /**< Message date */
|
|
|
|
Flags, /**< Message flags */
|
|
|
|
Priority, /**< Message priority */
|
|
|
|
Size, /**< Message size (in bytes) */
|
|
|
|
|
|
|
|
/* add new ones here... */
|
|
|
|
MailingList, /**< Mailing list */
|
|
|
|
ThreadId, /**< Thread Id */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* <private>
|
|
|
|
*/
|
2022-03-19 17:56:10 +01:00
|
|
|
_count_ /**< Number of FieldIds */
|
2022-02-23 08:29:37 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the number of Id values.
|
|
|
|
*
|
|
|
|
* @return the number.
|
|
|
|
*/
|
|
|
|
static constexpr size_t id_size()
|
|
|
|
{
|
|
|
|
return static_cast<size_t>(Id::_count_);
|
|
|
|
}
|
|
|
|
|
2022-03-03 23:02:52 +01:00
|
|
|
constexpr Xapian::valueno value_no() const {
|
|
|
|
return static_cast<Xapian::valueno>(id);
|
|
|
|
}
|
|
|
|
|
2022-02-23 08:29:37 +01:00
|
|
|
/**
|
|
|
|
* Field types
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
enum struct Type {
|
|
|
|
String, /**< String */
|
|
|
|
StringList, /**< List of strings */
|
|
|
|
ByteSize, /**< Size in bytes */
|
|
|
|
TimeT, /**< A time_t value */
|
|
|
|
Integer, /**< An integer */
|
|
|
|
};
|
|
|
|
|
2022-03-03 23:02:52 +01:00
|
|
|
constexpr bool is_string() const { return type == Type::String; }
|
|
|
|
constexpr bool is_string_list() const { return type == Type::StringList; }
|
|
|
|
constexpr bool is_byte_size() const { return type == Type::ByteSize; }
|
|
|
|
constexpr bool is_time_t() const { return type == Type::TimeT; }
|
|
|
|
constexpr bool is_integer() const { return type == Type::Integer; }
|
|
|
|
constexpr bool is_numerical() const { return is_byte_size() || is_time_t() || is_integer(); }
|
|
|
|
|
2022-02-23 08:29:37 +01:00
|
|
|
/**
|
|
|
|
* Field flags
|
|
|
|
* note: the differences for our purposes between a xapian field and a
|
|
|
|
* term: - there is only a single value for some item in per document
|
|
|
|
* (msg), ie. one value containing the list of To: addresses - there
|
|
|
|
* can be multiple terms, each containing e.g. one of the To:
|
|
|
|
* addresses - searching uses terms, but to display some field, it
|
|
|
|
* must be in the value (at least when using MuMsgIter)
|
2022-03-19 17:41:05 +01:00
|
|
|
*
|
|
|
|
* Rules (build-time enforced):
|
|
|
|
* - A field has at most one of Indexable, HasTerms, IsXapianBoolean and IsContact.
|
2022-02-23 08:29:37 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
enum struct Flag {
|
2022-03-19 17:41:05 +01:00
|
|
|
GMime = 1 << 0,
|
2022-02-23 08:29:37 +01:00
|
|
|
/**< Field retrieved through gmime */
|
2022-03-19 17:41:05 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Different kind of terms; at most one is true,
|
|
|
|
* and cannot be combined with IsContact. Compile-time enforced.
|
|
|
|
*/
|
|
|
|
NormalTerm = 1 << 2,
|
2022-02-23 08:29:37 +01:00
|
|
|
/**< Field is a searchable term */
|
2022-03-19 17:41:05 +01:00
|
|
|
BooleanTerm = 1 << 5,
|
|
|
|
/**< Field is a boolean search-term; wildcards do not work */
|
|
|
|
IndexableTerm = 1 << 1,
|
|
|
|
/**< Field has indexable text as term */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Contact flag cannot be combined with any of the term flags.
|
|
|
|
* This is compile-time enforced.
|
|
|
|
*/
|
|
|
|
Contact = 1 << 4,
|
|
|
|
/**< field contains one or more e-mail-addresses */
|
|
|
|
|
|
|
|
Value = 1 << 3,
|
2022-02-23 08:29:37 +01:00
|
|
|
/**< Field value is stored (so the literal value can be retrieved) */
|
2022-03-19 17:41:05 +01:00
|
|
|
|
|
|
|
DoNotCache = 1 << 6,
|
2022-02-23 08:29:37 +01:00
|
|
|
/**< don't cache this field in * the MuMsg cache */
|
2022-03-19 17:41:05 +01:00
|
|
|
Range = 1 << 7
|
|
|
|
/**< whether this is a range field (e.g., date, size)*/
|
2022-02-23 08:29:37 +01:00
|
|
|
};
|
|
|
|
|
2022-03-03 23:02:52 +01:00
|
|
|
constexpr bool any_of(Flag some_flag) const{
|
|
|
|
return (static_cast<int>(some_flag) & static_cast<int>(flags)) != 0;
|
|
|
|
}
|
|
|
|
|
2022-03-19 17:41:05 +01:00
|
|
|
constexpr bool is_gmime() const { return any_of(Flag::GMime); }
|
|
|
|
|
|
|
|
constexpr bool is_indexable_term() const { return any_of(Flag::IndexableTerm); }
|
|
|
|
constexpr bool is_boolean_term() const { return any_of(Flag::BooleanTerm); }
|
|
|
|
constexpr bool is_normal_term() const { return any_of(Flag::NormalTerm); }
|
|
|
|
|
2022-03-19 17:56:10 +01:00
|
|
|
constexpr bool is_searchable() const { return is_indexable_term() ||
|
|
|
|
is_boolean_term() ||
|
|
|
|
is_normal_term(); }
|
|
|
|
|
2022-03-19 17:41:05 +01:00
|
|
|
constexpr bool is_value() const { return any_of(Flag::Value); }
|
|
|
|
|
|
|
|
constexpr bool is_contact() const { return any_of(Flag::Contact); }
|
|
|
|
constexpr bool is_range() const { return any_of(Flag::Range); }
|
|
|
|
constexpr bool do_not_cache() const { return any_of(Flag::DoNotCache); }
|
|
|
|
|
2022-03-03 23:02:52 +01:00
|
|
|
|
2022-03-19 17:56:10 +01:00
|
|
|
|
2022-02-23 08:29:37 +01:00
|
|
|
/**
|
|
|
|
* Field members
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
Id id; /**< Id of the message field */
|
|
|
|
Type type; /**< Type of the message field */
|
|
|
|
std::string_view name; /**< Name of the message field */
|
|
|
|
std::string_view description; /**< Decription of the message field */
|
|
|
|
std::string_view example_query; /**< Example query */
|
|
|
|
char shortcut; /**< Shortcut for the message field; a..z */
|
|
|
|
Flag flags; /**< Flags */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convenience / helpers
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
constexpr char xapian_prefix() const
|
|
|
|
{ /* xapian uses uppercase shortcuts; toupper is not constexpr */
|
|
|
|
return shortcut == 0 ? 0 : shortcut - ('a' - 'A');
|
|
|
|
}
|
|
|
|
|
2022-03-03 23:02:52 +01:00
|
|
|
std::string xapian_term(const std::string& s="") const;
|
|
|
|
std::string xapian_term(std::string_view sv) const;
|
|
|
|
std::string xapian_term(char c) const;
|
2022-02-23 08:29:37 +01:00
|
|
|
};
|
|
|
|
|
2022-03-19 17:56:10 +01:00
|
|
|
MU_ENABLE_BITOPS(Field::Flag);
|
2022-02-23 08:29:37 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Sequence of _all_ message fields
|
|
|
|
*/
|
2022-03-19 17:56:10 +01:00
|
|
|
static constexpr std::array<Field, Field::id_size()>
|
|
|
|
Fields = {
|
2022-02-23 08:29:37 +01:00
|
|
|
{
|
|
|
|
// Bcc
|
|
|
|
{
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Id::Bcc,
|
|
|
|
Field::Type::String,
|
2022-02-23 08:29:37 +01:00
|
|
|
"bcc",
|
|
|
|
"Blind carbon-copy recipient",
|
|
|
|
"bcc:foo@example.com",
|
|
|
|
'h',
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Flag::GMime |
|
|
|
|
Field::Flag::Contact |
|
|
|
|
Field::Flag::Value
|
2022-03-19 17:41:05 +01:00
|
|
|
},
|
2022-02-23 08:29:37 +01:00
|
|
|
// HTML Body
|
|
|
|
{
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Id::BodyHtml,
|
|
|
|
Field::Type::String,
|
2022-02-23 08:29:37 +01:00
|
|
|
"body",
|
|
|
|
"Message html body",
|
|
|
|
{},
|
|
|
|
{},
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Flag::GMime |
|
|
|
|
Field::Flag::DoNotCache
|
2022-03-19 17:41:05 +01:00
|
|
|
},
|
2022-02-23 08:29:37 +01:00
|
|
|
// Body
|
|
|
|
{
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Id::BodyText,
|
|
|
|
Field::Type::String,
|
2022-02-23 08:29:37 +01:00
|
|
|
"body",
|
|
|
|
"Message plain-text body",
|
|
|
|
"body:capybara", // example
|
|
|
|
'b',
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Flag::GMime |
|
|
|
|
Field::Flag::IndexableTerm |
|
|
|
|
Field::Flag::DoNotCache
|
2022-03-19 17:41:05 +01:00
|
|
|
},
|
2022-02-23 08:29:37 +01:00
|
|
|
// Cc
|
|
|
|
{
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Id::Cc,
|
|
|
|
Field::Type::String,
|
2022-02-23 08:29:37 +01:00
|
|
|
"cc",
|
|
|
|
"Carbon-copy recipient",
|
|
|
|
"cc:quinn@example.com",
|
|
|
|
'c',
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Flag::GMime |
|
|
|
|
Field::Flag::Contact |
|
|
|
|
Field::Flag::Value},
|
2022-02-23 08:29:37 +01:00
|
|
|
|
|
|
|
// Embed
|
|
|
|
{
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Id::EmbeddedText,
|
|
|
|
Field::Type::String,
|
2022-02-23 08:29:37 +01:00
|
|
|
"embed",
|
|
|
|
"Embedded text",
|
|
|
|
"embed:war OR embed:peace",
|
|
|
|
'e',
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Flag::GMime |
|
|
|
|
Field::Flag::IndexableTerm |
|
|
|
|
Field::Flag::DoNotCache},
|
2022-02-23 08:29:37 +01:00
|
|
|
// File
|
|
|
|
{
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Id::File,
|
|
|
|
Field::Type::String,
|
2022-02-23 08:29:37 +01:00
|
|
|
"file",
|
|
|
|
"Attachment file name",
|
|
|
|
"file:/image\\.*.jpg/",
|
|
|
|
'j',
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Flag::GMime |
|
|
|
|
Field::Flag::NormalTerm |
|
|
|
|
Field::Flag::DoNotCache},
|
2022-02-23 08:29:37 +01:00
|
|
|
|
|
|
|
// From
|
|
|
|
{
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Id::From,
|
|
|
|
Field::Type::String,
|
2022-02-23 08:29:37 +01:00
|
|
|
"from",
|
|
|
|
"Message sender",
|
|
|
|
"from:jimbo",
|
|
|
|
'f',
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Flag::GMime |
|
|
|
|
Field::Flag::Contact |
|
|
|
|
Field::Flag::Value},
|
2022-02-23 08:29:37 +01:00
|
|
|
// Maildir
|
|
|
|
{
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Id::Maildir,
|
|
|
|
Field::Type::String,
|
2022-02-23 08:29:37 +01:00
|
|
|
"maildir",
|
|
|
|
"Maildir path for message",
|
|
|
|
"maildir:/private/archive",
|
|
|
|
'm',
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Flag::GMime |
|
|
|
|
Field::Flag::NormalTerm |
|
|
|
|
Field::Flag::Value},
|
2022-02-23 08:29:37 +01:00
|
|
|
// MIME
|
|
|
|
{
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Id::Mime,
|
|
|
|
Field::Type::String,
|
2022-02-23 08:29:37 +01:00
|
|
|
"mime",
|
|
|
|
"Attachment MIME-type",
|
|
|
|
"mime:image/jpeg",
|
|
|
|
'y',
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Flag::NormalTerm},
|
2022-02-23 08:29:37 +01:00
|
|
|
// Message-ID
|
|
|
|
{
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Id::MessageId,
|
|
|
|
Field::Type::String,
|
2022-02-23 08:29:37 +01:00
|
|
|
"msgid",
|
|
|
|
"Attachment MIME-type",
|
2022-03-26 15:19:08 +01:00
|
|
|
"msgid:abc@123",
|
2022-02-23 08:29:37 +01:00
|
|
|
'i',
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Flag::GMime |
|
|
|
|
Field::Flag::NormalTerm |
|
|
|
|
Field::Flag::Value},
|
2022-02-23 08:29:37 +01:00
|
|
|
// Path
|
|
|
|
{
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Id::Path,
|
|
|
|
Field::Type::String,
|
2022-02-23 08:29:37 +01:00
|
|
|
"path",
|
|
|
|
"File system path to message",
|
|
|
|
{},
|
2022-03-03 23:02:52 +01:00
|
|
|
'p',
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Flag::GMime |
|
|
|
|
Field::Flag::BooleanTerm |
|
|
|
|
Field::Flag::Value},
|
2022-02-23 08:29:37 +01:00
|
|
|
|
|
|
|
// Subject
|
|
|
|
{
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Id::Subject,
|
|
|
|
Field::Type::String,
|
2022-02-23 08:29:37 +01:00
|
|
|
"subject",
|
|
|
|
"Message subject",
|
|
|
|
"subject:wombat",
|
|
|
|
's',
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Flag::GMime |
|
|
|
|
Field::Flag::Value |
|
|
|
|
Field::Flag::IndexableTerm},
|
2022-02-23 08:29:37 +01:00
|
|
|
|
|
|
|
// To
|
|
|
|
{
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Id::To,
|
|
|
|
Field::Type::String,
|
2022-03-03 23:02:52 +01:00
|
|
|
"to",
|
2022-02-23 08:29:37 +01:00
|
|
|
"Message recipient",
|
|
|
|
"to:flimflam@example.com",
|
|
|
|
't',
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Flag::GMime |
|
|
|
|
Field::Flag::Contact |
|
|
|
|
Field::Flag::Value
|
2022-03-19 17:41:05 +01:00
|
|
|
},
|
2022-03-19 17:56:10 +01:00
|
|
|
// UID (internal)
|
|
|
|
{
|
|
|
|
Field::Id::Uid,
|
|
|
|
Field::Type::String,
|
|
|
|
"uid",
|
|
|
|
"Message recipient",
|
|
|
|
{},
|
|
|
|
'u',
|
|
|
|
Field::Flag::NormalTerm},
|
|
|
|
|
2022-02-23 08:29:37 +01:00
|
|
|
// References
|
|
|
|
{
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Id::References,
|
|
|
|
Field::Type::StringList,
|
2022-02-23 08:29:37 +01:00
|
|
|
"refs",
|
|
|
|
"Message references to other messages",
|
|
|
|
{},
|
|
|
|
'r',
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Flag::GMime |
|
|
|
|
Field::Flag::Value
|
2022-03-19 17:41:05 +01:00
|
|
|
},
|
2022-02-23 08:29:37 +01:00
|
|
|
// Tags
|
|
|
|
{
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Id::Tags,
|
|
|
|
Field::Type::StringList,
|
2022-02-23 08:29:37 +01:00
|
|
|
"tag",
|
|
|
|
"Message tags",
|
|
|
|
"tag:projectx",
|
|
|
|
'x',
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Flag::GMime |
|
|
|
|
Field::Flag::NormalTerm |
|
|
|
|
Field::Flag::Value
|
2022-03-19 17:41:05 +01:00
|
|
|
},
|
2022-02-23 08:29:37 +01:00
|
|
|
// Date
|
|
|
|
{
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Id::Date,
|
|
|
|
Field::Type::TimeT,
|
2022-02-23 08:29:37 +01:00
|
|
|
"date",
|
|
|
|
"Message date",
|
|
|
|
"date:20220101..20220505",
|
|
|
|
'd',
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Flag::GMime |
|
|
|
|
Field::Flag::Value |
|
|
|
|
Field::Flag::Range
|
2022-03-19 17:41:05 +01:00
|
|
|
},
|
2022-02-23 08:29:37 +01:00
|
|
|
// Flags
|
|
|
|
{
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Id::Flags,
|
|
|
|
Field::Type::Integer,
|
2022-02-23 08:29:37 +01:00
|
|
|
"flag",
|
|
|
|
"Message properties",
|
|
|
|
"flag:unread",
|
|
|
|
'g',
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Flag::GMime |
|
|
|
|
Field::Flag::NormalTerm |
|
|
|
|
Field::Flag::Value
|
2022-03-19 17:41:05 +01:00
|
|
|
},
|
2022-02-23 08:29:37 +01:00
|
|
|
// Priority
|
|
|
|
{
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Id::Priority,
|
|
|
|
Field::Type::Integer,
|
2022-02-23 08:29:37 +01:00
|
|
|
"prio",
|
|
|
|
"Priority",
|
|
|
|
"prio:high",
|
|
|
|
'p',
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Flag::GMime |
|
|
|
|
Field::Flag::NormalTerm |
|
|
|
|
Field::Flag::Value
|
2022-03-19 17:41:05 +01:00
|
|
|
},
|
2022-02-23 08:29:37 +01:00
|
|
|
// Size
|
|
|
|
{
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Id::Size,
|
|
|
|
Field::Type::ByteSize,
|
2022-02-23 08:29:37 +01:00
|
|
|
"size",
|
|
|
|
"Message size in bytes",
|
|
|
|
"size:1M..5M",
|
|
|
|
'z',
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Flag::GMime |
|
|
|
|
Field::Flag::Value |
|
|
|
|
Field::Flag::Range
|
2022-03-19 17:41:05 +01:00
|
|
|
},
|
2022-02-23 08:29:37 +01:00
|
|
|
// Mailing List
|
|
|
|
{
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Id::MailingList,
|
|
|
|
Field::Type::String,
|
2022-02-23 08:29:37 +01:00
|
|
|
"list",
|
|
|
|
"Mailing list (List-Id:)",
|
|
|
|
"list:mu-discuss.googlegroups.com",
|
|
|
|
'v',
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Flag::GMime |
|
|
|
|
Field::Flag::NormalTerm |
|
|
|
|
Field::Flag::Value
|
2022-03-19 17:41:05 +01:00
|
|
|
},
|
2022-02-23 08:29:37 +01:00
|
|
|
// ThreadId
|
|
|
|
{
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Id::ThreadId,
|
|
|
|
Field::Type::String,
|
2022-02-23 08:29:37 +01:00
|
|
|
"thread",
|
|
|
|
"Thread a message belongs to",
|
|
|
|
{},
|
|
|
|
'w',
|
2022-03-19 17:56:10 +01:00
|
|
|
Field::Flag::NormalTerm
|
2022-03-19 17:41:05 +01:00
|
|
|
},
|
2022-02-23 08:29:37 +01:00
|
|
|
}};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Convenience
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the message field for the given Id.
|
|
|
|
*
|
|
|
|
* @param id of the message field
|
|
|
|
*
|
|
|
|
* @return ref of the message field.
|
|
|
|
*/
|
2022-03-19 17:56:10 +01:00
|
|
|
constexpr const Field&
|
|
|
|
field_from_id(Field::Id id)
|
2022-02-23 08:29:37 +01:00
|
|
|
{
|
2022-03-19 17:56:10 +01:00
|
|
|
return Fields.at(static_cast<size_t>(id));
|
2022-02-23 08:29:37 +01:00
|
|
|
}
|
|
|
|
|
2022-03-03 23:02:52 +01:00
|
|
|
/**
|
|
|
|
* Invoke func for each message-field
|
|
|
|
*
|
|
|
|
* @param func some callable
|
|
|
|
*/
|
|
|
|
template <typename Func>
|
2022-03-19 17:56:10 +01:00
|
|
|
void field_for_each(Func&& func) {
|
|
|
|
for (const auto& field: Fields)
|
2022-03-03 23:02:52 +01:00
|
|
|
func(field);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Find a message field that satisfies some predicate
|
|
|
|
*
|
|
|
|
* @param pred the predicate (a callable)
|
|
|
|
*
|
|
|
|
* @return a message-field id, or nullopt if not found.
|
|
|
|
*/
|
|
|
|
template <typename Pred>
|
2022-03-26 15:19:08 +01:00
|
|
|
Option<Field> field_find_if(Pred&& pred) {
|
2022-03-19 17:56:10 +01:00
|
|
|
for (auto&& field: Fields)
|
2022-03-03 23:02:52 +01:00
|
|
|
if (pred(field))
|
2022-03-19 17:56:10 +01:00
|
|
|
return field;
|
2022-03-26 15:19:08 +01:00
|
|
|
return Nothing;
|
2022-03-03 23:02:52 +01:00
|
|
|
}
|
|
|
|
|
2022-02-23 08:29:37 +01:00
|
|
|
/**
|
|
|
|
* Get the the message-field id for the given name or shortcut
|
|
|
|
*
|
|
|
|
* @param name_or_shortcut
|
|
|
|
*
|
|
|
|
* @return the message-field-id or nullopt.
|
|
|
|
*/
|
2022-03-03 23:02:52 +01:00
|
|
|
static inline
|
2022-03-26 15:19:08 +01:00
|
|
|
Option<Field> field_from_shortcut(char shortcut) {
|
2022-03-19 17:56:10 +01:00
|
|
|
return field_find_if([&](auto&& field){
|
2022-03-03 23:02:52 +01:00
|
|
|
return field.shortcut == shortcut;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
static inline
|
2022-03-26 15:19:08 +01:00
|
|
|
Option<Field> field_from_name(const std::string& name) {
|
2022-03-03 23:02:52 +01:00
|
|
|
if (name.length() == 1)
|
2022-03-19 17:56:10 +01:00
|
|
|
return field_from_shortcut(name[0]);
|
2022-03-03 23:02:52 +01:00
|
|
|
else
|
2022-03-19 17:56:10 +01:00
|
|
|
return field_find_if([&](auto&& field){
|
2022-03-03 23:02:52 +01:00
|
|
|
return field.name == name;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2022-03-19 17:56:10 +01:00
|
|
|
* Get the Field::Id for some number, or nullopt if it does not match
|
2022-03-03 23:02:52 +01:00
|
|
|
*
|
|
|
|
* @param id an id number
|
|
|
|
*
|
2022-03-19 17:56:10 +01:00
|
|
|
* @return Field::Id or nullopt
|
2022-03-03 23:02:52 +01:00
|
|
|
*/
|
|
|
|
static inline
|
2022-03-26 15:19:08 +01:00
|
|
|
Option<Field> field_from_number(size_t id)
|
2022-03-03 23:02:52 +01:00
|
|
|
{
|
2022-03-19 17:56:10 +01:00
|
|
|
if (id >= static_cast<size_t>(Field::Id::_count_))
|
2022-03-26 15:19:08 +01:00
|
|
|
return Nothing;
|
2022-03-03 23:02:52 +01:00
|
|
|
else
|
2022-03-19 17:56:10 +01:00
|
|
|
return field_from_id(static_cast<Field::Id>(id));
|
2022-03-03 23:02:52 +01:00
|
|
|
}
|
|
|
|
|
2022-02-23 08:29:37 +01:00
|
|
|
|
|
|
|
} // namespace Mu
|
2022-03-19 17:56:10 +01:00
|
|
|
#endif /* MU_FIELDS_HH__ */
|