*: update code for Mu::MessageFlags

Migrate the code to use the new niceness
This commit is contained in:
Dirk-Jan C. Binnema 2022-02-16 22:06:00 +02:00
parent 473134a7b1
commit f6f17d5d6b
8 changed files with 136 additions and 237 deletions

View File

@ -17,6 +17,7 @@
** **
*/ */
#include "mu-guile-message.hh" #include "mu-guile-message.hh"
#include "mu-message-flags.hh"
#include <config.h> #include <config.h>
#include <glib-object.h> #include <glib-object.h>
@ -40,9 +41,7 @@ using namespace Mu;
/* some symbols */ /* some symbols */
static SCM SYMB_PRIO_LOW, SYMB_PRIO_NORMAL, SYMB_PRIO_HIGH; static SCM SYMB_PRIO_LOW, SYMB_PRIO_NORMAL, SYMB_PRIO_HIGH;
static SCM SYMB_FLAG_NEW, SYMB_FLAG_PASSED, SYMB_FLAG_REPLIED, SYMB_FLAG_SEEN, SYMB_FLAG_TRASHED, static std::array<SCM, AllMessageFlagInfos.size()> SYMB_FLAGS;
SYMB_FLAG_DRAFT, SYMB_FLAG_FLAGGED, SYMB_FLAG_SIGNED, SYMB_FLAG_ENCRYPTED, SYMB_FLAG_HAS_ATTACH,
SYMB_FLAG_UNREAD, SYMB_FLAG_LIST;
static SCM SYMB_CONTACT_TO, SYMB_CONTACT_CC, SYMB_CONTACT_BCC, SYMB_CONTACT_FROM; static SCM SYMB_CONTACT_TO, SYMB_CONTACT_CC, SYMB_CONTACT_BCC, SYMB_CONTACT_FROM;
struct _MuMsgWrapper { struct _MuMsgWrapper {
@ -72,11 +71,10 @@ mu_guile_msg_to_scm(MuMsg* msg)
SCM_RETURN_NEWSMOB(MSG_TAG, msgwrap); SCM_RETURN_NEWSMOB(MSG_TAG, msgwrap);
} }
struct _FlagData { typedef struct {
MuFlags flags; MessageFlags flags;
SCM lst; SCM lst;
}; } FlagData;
typedef struct _FlagData FlagData;
#define MU_GUILE_INITIALIZED_OR_ERROR \ #define MU_GUILE_INITIALIZED_OR_ERROR \
do { \ do { \
@ -89,45 +87,20 @@ typedef struct _FlagData FlagData;
} \ } \
} while (0) } while (0)
static void
check_flag(MuFlags flag, FlagData* fdata)
{
SCM flag_scm;
if (!(fdata->flags & flag))
return;
switch (flag) {
case MU_FLAG_NONE: flag_scm = SCM_UNDEFINED; break;
case MU_FLAG_NEW: flag_scm = SYMB_FLAG_NEW; break;
case MU_FLAG_PASSED: flag_scm = SYMB_FLAG_PASSED; break;
case MU_FLAG_REPLIED: flag_scm = SYMB_FLAG_REPLIED; break;
case MU_FLAG_SEEN: flag_scm = SYMB_FLAG_SEEN; break;
case MU_FLAG_TRASHED: flag_scm = SYMB_FLAG_TRASHED; break;
case MU_FLAG_SIGNED: flag_scm = SYMB_FLAG_SIGNED; break;
case MU_FLAG_DRAFT: flag_scm = SYMB_FLAG_DRAFT; break;
case MU_FLAG_FLAGGED: flag_scm = SYMB_FLAG_FLAGGED; break;
case MU_FLAG_ENCRYPTED: flag_scm = SYMB_FLAG_ENCRYPTED; break;
case MU_FLAG_HAS_ATTACH: flag_scm = SYMB_FLAG_HAS_ATTACH; break;
case MU_FLAG_UNREAD: flag_scm = SYMB_FLAG_UNREAD; break;
case MU_FLAG_LIST: flag_scm = SYMB_FLAG_LIST; break;
default: flag_scm = SCM_UNDEFINED;
}
fdata->lst = scm_append_x(scm_list_2(fdata->lst, scm_list_1(flag_scm)));
}
static SCM static SCM
get_flags_scm(MuMsg* msg) get_flags_scm(MuMsg* msg)
{ {
FlagData fdata; SCM lst{SCM_EOL};
const auto flags{mu_msg_get_flags(msg)};
fdata.flags = mu_msg_get_flags(msg); for (auto i = 0; i != AllMessageFlagInfos.size(); ++i) {
fdata.lst = SCM_EOL; const auto& info{AllMessageFlagInfos.at(i)};
if (any_of(info.flag & flags))
scm_append_x(scm_list_2(lst, scm_list_1(SYMB_FLAGS.at(i))));
}
mu_flags_foreach((MuFlagsForeachFunc)check_flag, &fdata); return lst;
return fdata.lst;
} }
static SCM static SCM
@ -488,19 +461,11 @@ define_symbols(void)
SYMB_PRIO_NORMAL = register_symbol("mu:prio:normal"); SYMB_PRIO_NORMAL = register_symbol("mu:prio:normal");
SYMB_PRIO_HIGH = register_symbol("mu:prio:high"); SYMB_PRIO_HIGH = register_symbol("mu:prio:high");
SYMB_FLAG_NEW = register_symbol("mu:flag:new"); for (auto i = 0U; i != AllMessageFlagInfos.size(); ++i) {
SYMB_FLAG_PASSED = register_symbol("mu:flag:passed"); const auto& info{AllMessageFlagInfos.at(i)};
SYMB_FLAG_REPLIED = register_symbol("mu:flag:replied"); const auto name = "mu:flag:" + std::string{info.name};
SYMB_FLAG_SEEN = register_symbol("mu:flag:seen"); SYMB_FLAGS[i] = register_symbol(name.c_str());
SYMB_FLAG_TRASHED = register_symbol("mu:flag:trashed"); }
SYMB_FLAG_DRAFT = register_symbol("mu:flag:draft");
SYMB_FLAG_FLAGGED = register_symbol("mu:flag:flagged");
SYMB_FLAG_SIGNED = register_symbol("mu:flag:signed");
SYMB_FLAG_ENCRYPTED = register_symbol("mu:flag:encrypted");
SYMB_FLAG_HAS_ATTACH = register_symbol("mu:flag:has-attach");
SYMB_FLAG_UNREAD = register_symbol("mu:flag:unread");
SYMB_FLAG_LIST = register_symbol("mu:flag:list");
} }
static struct { static struct {

View File

@ -344,15 +344,15 @@ looks_like_attachment(GMimeObject* part)
} }
static void static void
msg_cflags_cb(GMimeObject* parent, GMimeObject* part, MuFlags* flags) msg_cflags_cb(GMimeObject* parent, GMimeObject* part, MessageFlags* flags)
{ {
if (GMIME_IS_MULTIPART_SIGNED(part)) if (GMIME_IS_MULTIPART_SIGNED(part))
*flags |= MU_FLAG_SIGNED; *flags |= MessageFlags::Signed;
/* FIXME: An encrypted part might be signed at the same time. /* FIXME: An encrypted part might be signed at the same time.
* In that case the signed flag is lost. */ * In that case the signed flag is lost. */
if (GMIME_IS_MULTIPART_ENCRYPTED(part)) if (GMIME_IS_MULTIPART_ENCRYPTED(part))
*flags |= MU_FLAG_ENCRYPTED; *flags |= MessageFlags::Encrypted;
/* smime */ /* smime */
if (GMIME_IS_APPLICATION_PKCS7_MIME(part)) { if (GMIME_IS_APPLICATION_PKCS7_MIME(part)) {
@ -361,10 +361,10 @@ msg_cflags_cb(GMimeObject* parent, GMimeObject* part, MuFlags* flags)
if (pkcs7) { if (pkcs7) {
switch(pkcs7->smime_type) { switch(pkcs7->smime_type) {
case GMIME_SECURE_MIME_TYPE_ENVELOPED_DATA: case GMIME_SECURE_MIME_TYPE_ENVELOPED_DATA:
*flags |= MU_FLAG_ENCRYPTED; *flags |= MessageFlags::Encrypted;
break; break;
case GMIME_SECURE_MIME_TYPE_SIGNED_DATA: case GMIME_SECURE_MIME_TYPE_SIGNED_DATA:
*flags |= MU_FLAG_SIGNED; *flags |= MessageFlags::Signed;
break; break;
default: default:
break; break;
@ -372,27 +372,20 @@ msg_cflags_cb(GMimeObject* parent, GMimeObject* part, MuFlags* flags)
} }
} }
if (*flags & MU_FLAG_HAS_ATTACH) if (any_of(*flags & MessageFlags::HasAttachment))
return; return;
if (!GMIME_IS_PART(part)) if (!GMIME_IS_PART(part))
return; return;
if (*flags & MU_FLAG_HAS_ATTACH)
return;
if (looks_like_attachment(part)) if (looks_like_attachment(part))
*flags |= MU_FLAG_HAS_ATTACH; *flags |= MessageFlags::HasAttachment;
} }
static MessageFlags
static MuFlags
get_content_flags(MuMsgFile* self) get_content_flags(MuMsgFile* self)
{ {
MuFlags flags; MessageFlags flags{MessageFlags::None};
char* ml;
flags = MU_FLAG_NONE;
if (GMIME_IS_MESSAGE(self->_mime_msg)) { if (GMIME_IS_MESSAGE(self->_mime_msg)) {
/* toplevel */ /* toplevel */
@ -404,29 +397,29 @@ get_content_flags(MuMsgFile* self)
&flags); &flags);
} }
ml = get_mailing_list(self); char *ml{get_mailing_list(self)};
if (ml) { if (ml) {
flags |= MU_FLAG_LIST; flags |= MessageFlags::MailingList;
g_free(ml); g_free(ml);
} }
return flags; return flags;
} }
static MuFlags static MessageFlags
get_flags(MuMsgFile* self) get_flags(MuMsgFile* self)
{ {
MuFlags flags; g_return_val_if_fail(self, MessageFlags::None);
g_return_val_if_fail(self, MU_FLAG_INVALID); auto flags{mu_maildir_flags_from_path(self->_path)
.value_or(MessageFlags::None)};
flags = mu_maildir_get_flags_from_path(self->_path);
flags |= get_content_flags(self); flags |= get_content_flags(self);
/* pseudo-flag --> unread means either NEW or NOT SEEN, just /* pseudo-flag --> unread means either NEW or NOT SEEN, just
* for searching convenience */ * for searching convenience */
if ((flags & MU_FLAG_NEW) || !(flags & MU_FLAG_SEEN)) if (any_of(flags & MessageFlags::New) ||
flags |= MU_FLAG_UNREAD; none_of(flags & MessageFlags::Seen))
flags |= MessageFlags::Unread;
return flags; return flags;
} }

View File

@ -19,6 +19,7 @@
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include "mu-message-flags.hh"
#include "mu-query-results.hh" #include "mu-query-results.hh"
#include "utils/mu-str.h" #include "utils/mu-str.h"
#include "mu-msg.hh" #include "mu-msg.hh"
@ -138,27 +139,19 @@ add_contacts(Sexp::List& list, MuMsg* msg)
add_list_post(list, msg); add_list_post(list, msg);
} }
typedef struct {
Sexp::List flaglist;
MuFlags msgflags;
} FlagData;
static void
each_flag(MuFlags flag, FlagData* fdata)
{
if (flag & fdata->msgflags)
fdata->flaglist.add(Sexp::make_symbol(mu_flag_name(flag)));
}
static void static void
add_flags(Sexp::List& list, MuMsg* msg) add_flags(Sexp::List& list, MuMsg* msg)
{ {
FlagData fdata{}; Sexp::List flaglist;
fdata.msgflags = mu_msg_get_flags(msg); const auto flags{mu_msg_get_flags(msg)};
for (auto&& info: AllMessageFlagInfos)
if (any_of(flags & info.flag))
flaglist.add(Sexp::make_symbol_sv(info.name));
mu_flags_foreach((MuFlagsForeachFunc)each_flag, &fdata); if (!flaglist.empty())
if (!fdata.flaglist.empty()) list.add_prop(":flags", Sexp::make_list(std::move(flaglist)));
list.add_prop(":flags", Sexp::make_list(std::move(fdata.flaglist)));
} }
static char* static char*

View File

@ -20,9 +20,12 @@
#ifndef MU_MSG_HH__ #ifndef MU_MSG_HH__
#define MU_MSG_HH__ #define MU_MSG_HH__
#include <mu-flags.hh> #include <utils/mu-result.hh>
#include <mu-msg-fields.h>
#include <mu-message-flags.hh>
#include <mu-message-priority.hh> #include <mu-message-priority.hh>
#include <mu-msg-fields.h>
#include <utils/mu-util.h> #include <utils/mu-util.h>
#include <utils/mu-utils.hh> #include <utils/mu-utils.hh>
#include <utils/mu-option.hh> #include <utils/mu-option.hh>
@ -294,10 +297,10 @@ time_t mu_msg_get_date(MuMsg* msg);
* *
* @param msg valid MuMsg* instance * @param msg valid MuMsg* instance
* *
* @return the file/content flags as logically OR'd #MuMsgFlags or 0 * @return the file/content flags as logically OR'd #Mu::MessageFlags.
* if there are none. Non-standard flags are ignored. * Non-standard flags are ignored.
*/ */
MuFlags mu_msg_get_flags(MuMsg* msg); MessageFlags mu_msg_get_flags(MuMsg* msg);
/** /**
* get the file size in bytes of this message * get the file size in bytes of this message
@ -417,39 +420,25 @@ gboolean mu_msg_is_readable(MuMsg* self);
* *
* @param msg a message with an existing file system path in an actual * @param msg a message with an existing file system path in an actual
* maildir * maildir
* @param maildir the subdir where the message should go, relative to * @param root_maildir_path file system path for the root-maildir for this message
* e.g., /home/user/Maildir
* @param target_maildir the subdir where the message should go, relative to
* rootmaildir. e.g. "/archive" * rootmaildir. e.g. "/archive"
* @param flags to set for the target (influences the filename, path) * @param flags to set for the target (influences the filename, path)
* @param silently ignore the src=target case (return TRUE) * @param silently ignore the src=target case (return TRUE)
* @param new_name whether to create a new unique name, or keep the * @param new_name whether to create a new unique name, or keep the
* old one * old one
* @param err (may be NULL) may contain error information; note if the * @param err receives error information
* function return FALSE, err is not set for all error condition
* (ie. not for parameter error
* *
* @return TRUE if it worked, FALSE otherwise * @return TRUE if it worked, FALSE otherwise
*/ */
gboolean mu_msg_move_to_maildir(MuMsg* msg, bool mu_msg_move_to_maildir(MuMsg* msg,
const char* maildir, const std::string& root_maildir_path,
MuFlags flags, const std::string& target_maildir,
gboolean ignore_dups, MessageFlags flags,
gboolean new_name, bool ignore_dups,
GError** err); bool new_name,
GError** err);
/**
* Tickle a message -- ie., rename a message to some new semi-random name,while
* maintaining the maildir and flags. This can be useful when dealing with
* third-party tools such as mbsync that depend on changed filenames.
*
* @param msg a message with an existing file system path in an actual
* maildir
* @param err (may be NULL) may contain error information; note if the
* function return FALSE, err is not set for all error condition
* (ie. not for parameter error
*
* @return TRUE if it worked, FALSE otherwise
*/
gboolean mu_msg_tickle(MuMsg* msg, GError** err);
enum _MuMsgContactType { /* Reply-To:? */ enum _MuMsgContactType { /* Reply-To:? */
MU_MSG_CONTACT_TYPE_TO = 0, MU_MSG_CONTACT_TYPE_TO = 0,
@ -545,24 +534,6 @@ void mu_msg_contact_foreach(MuMsg* msg, MuMsgContactForeachFunc func, gpointer u
const char* mu_str_display_contact_s(const char* str) G_GNUC_CONST; const char* mu_str_display_contact_s(const char* str) G_GNUC_CONST;
char* mu_str_display_contact(const char* str) G_GNUC_WARN_UNUSED_RESULT; char* mu_str_display_contact(const char* str) G_GNUC_WARN_UNUSED_RESULT;
/**
* get a display string for a given set of flags, OR'ed in
* @param flags; one character per flag:
* D=draft,F=flagged,N=new,P=passed,R=replied,S=seen,T=trashed
* a=has-attachment,s=signed, x=encrypted
*
* mu_str_file_flags_s returns a ptr to a static buffer,
* while mu_str_file_flags returns dynamically allocated
* memory that must be freed after use.
*
* @param flags file flags
*
* @return a string representation of the flags; see above
* for what to do with it
*/
const char* mu_str_flags_s(MuFlags flags) G_GNUC_CONST;
char* mu_str_flags(MuFlags flags) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
struct QueryMatch; struct QueryMatch;
/** /**

View File

@ -116,13 +116,13 @@ process_value(const std::string& field, const std::string& value)
return std::string(1, value[0]); return std::string(1, value[0]);
} break; } break;
case MU_MSG_FIELD_ID_FLAGS: { case MU_MSG_FIELD_ID_FLAGS:
const auto flag = mu_flag_char_from_name(value.c_str()); if (const auto info{message_flag_info(value)}; info)
if (flag) return std::string(1, ::tolower(info->shortcut));
return std::string(1, tolower(flag)); break;
} break;
default: break; default:
break;
} }
return value; // XXX prio/flags, etc. alias return value; // XXX prio/flags, etc. alias

View File

@ -35,6 +35,8 @@
#include <vector> #include <vector>
#include <xapian.h> #include <xapian.h>
#include "mu-message-flags.hh"
#include "mu-msg-fields.h"
#include "mu-store.hh" #include "mu-store.hh"
#include "mu-query.hh" #include "mu-query.hh"
#include "utils/mu-str.h" #include "utils/mu-str.h"
@ -62,6 +64,36 @@ constexpr auto DefaultMaxMessageSize = 100'000'000U;
constexpr auto ExpectedSchemaVersion = MU_STORE_SCHEMA_VERSION; constexpr auto ExpectedSchemaVersion = MU_STORE_SCHEMA_VERSION;
/**
* calculate a 64-bit hash for the given string, based on a combination of the
* DJB and BKDR hash functions.
*
* @param a string
*
* @return the hash
*/
size_t get_hash64 (const char* str)
{
guint32 djbhash;
guint32 bkdrhash;
guint32 bkdrseed;
guint64 hash;
djbhash = 5381;
bkdrhash = 0;
bkdrseed = 1313;
for(unsigned u = 0U; str[u]; ++u) {
djbhash = ((djbhash << 5) + djbhash) + str[u];
bkdrhash = bkdrhash * bkdrseed + str[u];
}
hash = djbhash;
return (hash<<32) | bkdrhash;
}
/* we cache these prefix strings, so we don't have to allocate them all /* we cache these prefix strings, so we don't have to allocate them all
* the time; this should save 10-20 string allocs per message */ * the time; this should save 10-20 string allocs per message */
G_GNUC_CONST static const std::string& G_GNUC_CONST static const std::string&
@ -79,16 +111,6 @@ prefix(MuMsgFieldId mfid)
return fields[mfid]; return fields[mfid];
} }
static void
add_synonym_for_flag(MuFlags flag, Xapian::WritableDatabase* db)
{
static const std::string pfx(prefix(MU_MSG_FIELD_ID_FLAGS));
db->clear_synonyms(pfx + mu_flag_name(flag));
db->add_synonym(pfx + mu_flag_name(flag),
pfx + (std::string(1, (char)(tolower(mu_flag_char(flag))))));
}
struct Store::Private { struct Store::Private {
enum struct XapianOpts { ReadOnly, Open, CreateOverwrite, InMemory }; enum struct XapianOpts { ReadOnly, Open, CreateOverwrite, InMemory };
@ -207,8 +229,13 @@ struct Store::Private {
void add_synonyms() void add_synonyms()
{ {
mu_flags_foreach((MuFlagsForeachFunc)add_synonym_for_flag, for (auto&& info: AllMessageFlagInfos) {
&writable_db()); const auto s1{prefix(MU_MSG_FIELD_ID_FLAGS) + std::string{info.name}};
const auto s2{prefix(MU_MSG_FIELD_ID_FLAGS) + std::string{1,info.shortcut}};
writable_db().clear_synonyms(s1);
writable_db().clear_synonyms(s2);
writable_db().add_synonym(s1, s2);
}
for (auto&& prio : AllMessagePriorities) { for (auto&& prio : AllMessagePriorities) {
const auto s1{prefix(MU_MSG_FIELD_ID_PRIO) + to_string(prio)}; const auto s1{prefix(MU_MSG_FIELD_ID_PRIO) + to_string(prio)};
@ -293,7 +320,7 @@ struct Store::Private {
static void static void
hash_str(char* buf, size_t buf_size, const char* data) hash_str(char* buf, size_t buf_size, const char* data)
{ {
g_snprintf(buf, buf_size, "016%" PRIx64, mu_util_get_hash(data)); g_snprintf(buf, buf_size, "016%" PRIx64, get_hash64(data));
} }
static std::string static std::string
@ -687,45 +714,6 @@ add_terms_values_size(Xapian::Document& doc, MuMsg* msg, MuMsgFieldId mfid)
doc.add_value((Xapian::valueno)mfid, szstr); doc.add_value((Xapian::valueno)mfid, szstr);
} }
G_GNUC_CONST
static const std::string&
flag_val(char flagchar)
{
static const std::string pfx(prefix(MU_MSG_FIELD_ID_FLAGS)),
draftstr(pfx + (char)tolower(mu_flag_char(MU_FLAG_DRAFT))),
flaggedstr(pfx + (char)tolower(mu_flag_char(MU_FLAG_FLAGGED))),
passedstr(pfx + (char)tolower(mu_flag_char(MU_FLAG_PASSED))),
repliedstr(pfx + (char)tolower(mu_flag_char(MU_FLAG_REPLIED))),
seenstr(pfx + (char)tolower(mu_flag_char(MU_FLAG_SEEN))),
trashedstr(pfx + (char)tolower(mu_flag_char(MU_FLAG_TRASHED))),
newstr(pfx + (char)tolower(mu_flag_char(MU_FLAG_NEW))),
signedstr(pfx + (char)tolower(mu_flag_char(MU_FLAG_SIGNED))),
cryptstr(pfx + (char)tolower(mu_flag_char(MU_FLAG_ENCRYPTED))),
attachstr(pfx + (char)tolower(mu_flag_char(MU_FLAG_HAS_ATTACH))),
unreadstr(pfx + (char)tolower(mu_flag_char(MU_FLAG_UNREAD))),
liststr(pfx + (char)tolower(mu_flag_char(MU_FLAG_LIST)));
switch (flagchar) {
case 'D': return draftstr;
case 'F': return flaggedstr;
case 'P': return passedstr;
case 'R': return repliedstr;
case 'S': return seenstr;
case 'T': return trashedstr;
case 'N': return newstr;
case 'z': return signedstr;
case 'x': return cryptstr;
case 'a': return attachstr;
case 'l': return liststr;
case 'u': return unreadstr;
default: g_return_val_if_reached(flaggedstr); return flaggedstr;
}
}
static const std::string& static const std::string&
prio_val(MessagePriority prio) prio_val(MessagePriority prio)
{ {
@ -760,13 +748,12 @@ add_terms_values_number(Xapian::Document& doc, MuMsg* msg, MuMsgFieldId mfid)
doc.add_value((Xapian::valueno)mfid, numstr); doc.add_value((Xapian::valueno)mfid, numstr);
if (mfid == MU_MSG_FIELD_ID_FLAGS) { if (mfid == MU_MSG_FIELD_ID_FLAGS) {
const char* cur = mu_flags_to_str_s((MuFlags)num, (MuFlagType)MU_FLAG_TYPE_ANY); static const std::string pfx(prefix(MU_MSG_FIELD_ID_FLAGS));
g_return_if_fail(cur); const auto flags{static_cast<MessageFlags>(num)};
while (*cur) { for (auto&& info: AllMessageFlagInfos) {
add_term(doc, flag_val(*cur)); if (any_of(info.flag & flags))
++cur; add_term(doc, pfx + static_cast<char>(::tolower(info.shortcut)));
} }
} else if (mfid == MU_MSG_FIELD_ID_PRIO) } else if (mfid == MU_MSG_FIELD_ID_PRIO)
add_term(doc, prio_val(static_cast<MessagePriority>(num))); add_term(doc, prio_val(static_cast<MessagePriority>(num)));
} }
@ -893,7 +880,7 @@ add_terms_values_attach(Xapian::Document& doc, MuMsg* msg, MuMsgFieldId mfid)
static void static void
add_terms_values_body(Xapian::Document& doc, MuMsg* msg, MuMsgFieldId mfid) add_terms_values_body(Xapian::Document& doc, MuMsg* msg, MuMsgFieldId mfid)
{ {
if (mu_msg_get_flags(msg) & MU_FLAG_ENCRYPTED) if (any_of(mu_msg_get_flags(msg) & MessageFlags::Encrypted))
return; /* ignore encrypted bodies */ return; /* ignore encrypted bodies */
auto str = mu_msg_get_body_text(msg, MU_MSG_OPTION_NONE); auto str = mu_msg_get_body_text(msg, MU_MSG_OPTION_NONE);

View File

@ -43,11 +43,6 @@ test('test_query',
'test-query.cc', 'test-query.cc',
install: false, install: false,
dependencies: [glib_dep, lib_mu_dep, lib_test_mu_common_dep])) dependencies: [glib_dep, lib_mu_dep, lib_test_mu_common_dep]))
test('test_flags',
executable('test-flags',
'test-mu-flags.cc',
install: false,
dependencies: [glib_dep, lib_mu_dep, lib_test_mu_common_dep]))
test('test_tokenizer', test('test_tokenizer',
executable('test-tokenizer', executable('test-tokenizer',

View File

@ -145,7 +145,8 @@ test_mu_msg_02(void)
i = 0; i = 0;
mu_msg_contact_foreach(msg, (MuMsgContactForeachFunc)check_contact_02, &i); mu_msg_contact_foreach(msg, (MuMsgContactForeachFunc)check_contact_02, &i);
g_assert_cmpint(i, ==, 2); g_assert_cmpint(i, ==, 2);
g_assert_cmpuint(mu_msg_get_flags(msg), ==, MU_FLAG_SEEN | MU_FLAG_LIST); g_print("flags: %s\n", Mu::message_flags_to_string(mu_msg_get_flags(msg)).c_str());
g_assert_true(mu_msg_get_flags(msg) == (MessageFlags::Seen|MessageFlags::MailingList));
mu_msg_unref(msg); mu_msg_unref(msg);
} }
@ -173,9 +174,7 @@ test_mu_msg_03(void)
g_assert_cmpstr((char*)params->data, ==, "charset"); g_assert_cmpstr((char*)params->data, ==, "charset");
params = g_slist_next(params); params = g_slist_next(params);
g_assert_cmpstr((char*)params->data, ==, "UTF-8"); g_assert_cmpstr((char*)params->data, ==, "UTF-8");
g_assert_true(mu_msg_get_flags(msg) == (MessageFlags::Unread));
g_assert_cmpuint(mu_msg_get_flags(msg), ==, MU_FLAG_UNREAD); /* not seen => unread */
mu_msg_unref(msg); mu_msg_unref(msg);
} }
@ -191,7 +190,11 @@ test_mu_msg_04(void)
g_assert_true(mu_msg_get_prio(msg) /* 'low' */ g_assert_true(mu_msg_get_prio(msg) /* 'low' */
== Mu::MessagePriority::Normal); == Mu::MessagePriority::Normal);
g_assert_cmpuint(mu_msg_get_date(msg), ==, 0); g_assert_cmpuint(mu_msg_get_date(msg), ==, 0);
g_assert_cmpuint(mu_msg_get_flags(msg), ==, MU_FLAG_HAS_ATTACH | MU_FLAG_UNREAD); g_assert_true(mu_msg_get_flags(msg) ==
(MessageFlags::HasAttachment|MessageFlags::Unread));
g_assert_true(mu_msg_get_flags(msg) ==
(MessageFlags::HasAttachment|MessageFlags::Unread));
mu_msg_unref(msg); mu_msg_unref(msg);
} }
@ -204,9 +207,9 @@ test_mu_msg_multimime(void)
/* ie., are text parts properly concatenated? */ /* ie., are text parts properly concatenated? */
g_assert_cmpstr(mu_msg_get_subject(msg), ==, "multimime"); g_assert_cmpstr(mu_msg_get_subject(msg), ==, "multimime");
g_assert_cmpstr(mu_msg_get_body_text(msg, MU_MSG_OPTION_NONE), ==, "abcdef"); g_assert_cmpstr(mu_msg_get_body_text(msg, MU_MSG_OPTION_NONE), ==, "abcdef");
g_assert_cmpuint(mu_msg_get_flags(msg), g_assert_true(mu_msg_get_flags(msg) ==
==, (MessageFlags::HasAttachment|MessageFlags::Flagged|MessageFlags::Seen));
(MuFlags)(MU_FLAG_FLAGGED | MU_FLAG_SEEN | MU_FLAG_HAS_ATTACH));
mu_msg_unref(msg); mu_msg_unref(msg);
} }
@ -216,29 +219,21 @@ test_mu_msg_flags(void)
unsigned u; unsigned u;
struct { struct {
const char* path; const char* path;
MuFlags flags; MessageFlags flags;
} msgflags[] = {{MU_TESTMAILDIR4 "/multimime!2,FS", } msgflags[] = {{MU_TESTMAILDIR4 "/multimime!2,FS",
(MuFlags)(MU_FLAG_FLAGGED | MU_FLAG_SEEN | MU_FLAG_HAS_ATTACH)}, (MessageFlags::Flagged | MessageFlags::Seen |
{MU_TESTMAILDIR4 "/special!2,Sabc", MU_FLAG_SEEN} MessageFlags::HasAttachment)},
{MU_TESTMAILDIR4 "/special!2,Sabc",
(MessageFlags::Seen|MessageFlags::HasAttachment)}
}; };
for (u = 0; u != G_N_ELEMENTS(msgflags); ++u) { for (u = 0; u != G_N_ELEMENTS(msgflags); ++u) {
MuMsg* msg; MuMsg* msg;
MuFlags flags;
g_assert((msg = get_msg(msgflags[u].path))); g_assert((msg = get_msg(msgflags[u].path)));
flags = mu_msg_get_flags(msg); const auto flags{mu_msg_get_flags(msg)};
//g_print("flags: %s\n", Mu::message_flags_to_string(flags).c_str());
if (g_test_verbose()) g_assert_true(flags == msgflags[u].flags);
g_print("=> %s [ %s, %u] <=> [ %s, %u]\n",
msgflags[u].path,
mu_flags_to_str_s(msgflags[u].flags, MU_FLAG_TYPE_ANY),
(unsigned)msgflags[u].flags,
mu_flags_to_str_s(flags, MU_FLAG_TYPE_ANY),
(unsigned)flags);
g_assert_cmpuint(flags, ==, msgflags[u].flags);
mu_msg_unref(msg); mu_msg_unref(msg);
} }
} }