message: contact: remove ::Type, use Field

Don't need a special Type {} in Contact, when we have more-or-less the same info
in Field.
This commit is contained in:
Dirk-Jan C. Binnema
2022-03-19 18:38:30 +02:00
parent a23c99ff7e
commit d4285975b3
5 changed files with 76 additions and 111 deletions

View File

@ -18,11 +18,13 @@
*/ */
#include "mu-message-contact.hh" #include "mu-message-contact.hh"
#include "mu-message.hh"
#include <gmime/gmime.h> #include <gmime/gmime.h>
#include <glib.h> #include <glib.h>
using namespace Mu; using namespace Mu;
using namespace Mu::Message;
std::string std::string
MessageContact::display_name() const MessageContact::display_name() const
@ -35,8 +37,7 @@ MessageContact::display_name() const
Mu::MessageContacts Mu::MessageContacts
Mu::make_message_contacts(InternetAddressList* addr_lst, Mu::make_message_contacts(InternetAddressList* addr_lst,
MessageContact::Type type, Field::Id field_id, ::time_t message_date)
::time_t message_date)
{ {
MessageContacts contacts; MessageContacts contacts;
size_t num{}; size_t num{};
@ -59,7 +60,7 @@ Mu::make_message_contacts(InternetAddressList* addr_lst,
continue; continue;
contacts.push_back(MessageContact{email, name ? name : "", contacts.push_back(MessageContact{email, name ? name : "",
type, message_date}); field_id, message_date});
++num; ++num;
} }
@ -69,7 +70,7 @@ Mu::make_message_contacts(InternetAddressList* addr_lst,
Mu::MessageContacts Mu::MessageContacts
Mu::make_message_contacts(const std::string& addrs, Mu::make_message_contacts(const std::string& addrs,
MessageContact::Type type, Field::Id field_id,
::time_t message_date) ::time_t message_date)
{ {
auto addr_list = internet_address_list_parse(NULL, addrs.c_str()); auto addr_list = internet_address_list_parse(NULL, addrs.c_str());
@ -78,7 +79,7 @@ Mu::make_message_contacts(const std::string& addrs,
return {}; return {};
} }
auto contacts{make_message_contacts(addr_list, type, message_date)}; auto contacts{make_message_contacts(addr_list, field_id, message_date)};
g_object_unref(addr_list); g_object_unref(addr_list);
return contacts; return contacts;
@ -109,13 +110,13 @@ test_ctor_foo()
MessageContact c{ MessageContact c{
"foo@example.com", "foo@example.com",
"Foo Bar", "Foo Bar",
MessageContact::Type::Bcc, Field::Id::Bcc,
1645214647 1645214647
}; };
assert_equal(c.email, "foo@example.com"); assert_equal(c.email, "foo@example.com");
assert_equal(c.name, "Foo Bar"); assert_equal(c.name, "Foo Bar");
g_assert_true(c.type == MessageContact::Type::Bcc); g_assert_true(c.field_id == Field::Id::Bcc);
g_assert_cmpuint(c.message_date,==,1645214647); g_assert_cmpuint(c.message_date,==,1645214647);
assert_equal(c.display_name(), "Foo Bar <foo@example.com>"); assert_equal(c.display_name(), "Foo Bar <foo@example.com>");
@ -178,12 +179,12 @@ test_make_contacts()
internet_address_list_parse(NULL, str)}; internet_address_list_parse(NULL, str)};
g_assert_true(lst); g_assert_true(lst);
const auto addrs{make_message_contacts(lst, MessageContact::Type::Cc, 54321 )}; const auto addrs{make_message_contacts(lst, Field::Id::Cc, 54321 )};
g_object_unref(lst); g_object_unref(lst);
g_assert_cmpuint(addrs.size(),==,3); g_assert_cmpuint(addrs.size(),==,3);
const auto addrs2{make_message_contacts(str, MessageContact::Type::To, 12345 )}; const auto addrs2{make_message_contacts(str, Field::Id::To, 12345 )};
g_assert_cmpuint(addrs2.size(),==,3); g_assert_cmpuint(addrs2.size(),==,3);
assert_equal(addrs2[0].name, "Abc"); assert_equal(addrs2[0].name, "Abc");
@ -201,7 +202,7 @@ test_make_contacts_2()
"De\nf <baa@example.com>, " "De\nf <baa@example.com>, "
"\tGhi <zzz@example.com>"; "\tGhi <zzz@example.com>";
const auto addrs2{make_message_contacts(str, MessageContact::Type::Bcc, 12345 )}; const auto addrs2{make_message_contacts(str, Field::Id::Bcc, 12345 )};
g_assert_cmpuint(addrs2.size(),==,3); g_assert_cmpuint(addrs2.size(),==,3);
assert_equal(addrs2[0].name, "Äbc"); assert_equal(addrs2[0].name, "Äbc");
@ -221,7 +222,7 @@ test_make_contacts_err()
InternetAddressList *lst{ internet_address_list_parse(NULL, "")}; InternetAddressList *lst{ internet_address_list_parse(NULL, "")};
g_assert_false(lst); g_assert_false(lst);
const auto addrs{make_message_contacts("", MessageContact::Type::To, 77777)}; const auto addrs{make_message_contacts("", Field::Id::To, 77777)};
g_assert_true(addrs.empty()); g_assert_true(addrs.empty());
} }

View File

@ -44,31 +44,19 @@ namespace Mu {
*/ */
size_t lowercase_hash(const std::string& s); size_t lowercase_hash(const std::string& s);
struct MessageContact { struct MessageContact {
/**
* Contact types
*/
enum struct Type {
To, /**< To recipient */
From, /**< Sender */
Cc, /**< Cc recipient */
Bcc, /**< Bcc recipient */
ReplyTo, /**< Reply-To wannabe recipient */
Unknown, /**< Unknown type */
};
/** /**
* Construct a new MessageContact * Construct a new MessageContact
* *
* @param email_ email address * @param email_ email address
* @param name_ name or empty * @param name_ name or empty
* @param type_ contact type * @param field_id_ contact field id, or {}
* @param message_date_ data for the message for this contact * @param message_date_ data for the message for this contact
*/ */
MessageContact(const std::string& email_, const std::string& name_ = "", MessageContact(const std::string& email_, const std::string& name_ = "",
Type type_ = Type::Unknown, time_t message_date_ = 0) std::optional<MessageField::Id> field_id_ = {},
: email{email_}, name{name_}, type{type_}, time_t message_date_ = 0)
: email{email_}, name{name_}, field_id{field_id_},
message_date{message_date_}, personal{}, frequency{1}, tstamp{} message_date{message_date_}, personal{}, frequency{1}, tstamp{}
{ cleanup_name(); } { cleanup_name(); }
@ -85,7 +73,7 @@ struct MessageContact {
MessageContact(const std::string& email_, const std::string& name_, MessageContact(const std::string& email_, const std::string& name_,
time_t message_date_, bool personal_, size_t freq_, time_t message_date_, bool personal_, size_t freq_,
int64_t tstamp_) int64_t tstamp_)
: email{email_}, name{name_}, type{Type::Unknown}, : email{email_}, name{name_}, field_id{},
message_date{message_date_}, personal{personal_}, frequency{freq_}, message_date{message_date_}, personal{personal_}, frequency{freq_},
tstamp{tstamp_} tstamp{tstamp_}
{ cleanup_name();} { cleanup_name();}
@ -126,34 +114,13 @@ struct MessageContact {
return cached_hash; return cached_hash;
} }
/**
* Get the MessageField for this contact-type, if any.
*
* @return the message-field or nullopt.
*/
constexpr std::optional<MessageField> const field() {
switch(type){
case Type::From:
return message_field(MessageField::Id::From);
case Type::To:
return message_field(MessageField::Id::To);
case Type::Cc:
return message_field(MessageField::Id::Cc);
case Type::Bcc:
return message_field(MessageField::Id::Bcc);
default:
return std::nullopt;
}
}
/* /*
* data members * data members
*/ */
std::string email; /**< Email address for this contact.Not empty */ std::string email; /**< Email address for this contact.Not empty */
std::string name; /**< Name for this contact; can be empty. */ std::string name; /**< Name for this contact; can be empty. */
Type type{Type::Unknown}; /**< Type of contact */ std::optional<MessageField::Id> field_id; /**< Field Id of contact or nullopt */
::time_t message_date; /**< date of the message from which the ::time_t message_date; /**< date of the message from which the
* contact originates */ * contact originates */
bool personal; /**< A personal message? */ bool personal; /**< A personal message? */
@ -174,7 +141,7 @@ using MessageContacts = std::vector<MessageContact>;
* Create a sequence of MessageContact objects from an InternetAddressList * Create a sequence of MessageContact objects from an InternetAddressList
* *
* @param addr_lst an address list * @param addr_lst an address list
* @param type the type of addresses * @param field_id the field_id for message field for these addresses
* @param message_date the date of the message from which the InternetAddressList * @param message_date the date of the message from which the InternetAddressList
* originates. * originates.
* *
@ -182,20 +149,20 @@ using MessageContacts = std::vector<MessageContact>;
*/ */
MessageContacts MessageContacts
make_message_contacts(/*const*/ struct _InternetAddressList* addr_lst, make_message_contacts(/*const*/ struct _InternetAddressList* addr_lst,
MessageContact::Type type, ::time_t message_date); MessageField::Id field_id, ::time_t message_date);
/** /**
* Create a sequence of MessageContact objects from an InternetAddressList * Create a sequence of MessageContact objects from an InternetAddressList
* *
* @param addrs a string with one more valid addresses (as per internet_address_list_parse()) * @param addrs a string with one more valid addresses (as per internet_address_list_parse())
* @param type the type of addresses * @param field_id the field_id for message field for these addresses
* @param message_date the date of the message from which the addresses originate * @param message_date the date of the message from which the addresses originate
* *
* @return a sequence of MessageContact objects. * @return a sequence of MessageContact objects.
*/ */
MessageContacts MessageContacts
make_message_contacts(const std::string& addrs, make_message_contacts(const std::string& addrs,
MessageContact::Type type, ::time_t message_date); MessageField::Id field_id, ::time_t message_date);
} // namespace Mu } // namespace Mu
/** /**
@ -207,7 +174,4 @@ template<> struct std::hash<Mu::MessageContact> {
} }
}; };
#endif /* MU_MESSAGE_CONTACT_HH__ */ #endif /* MU_MESSAGE_CONTACT_HH__ */

View File

@ -19,7 +19,7 @@
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include "mu-message-flags.hh" #include "mu-message.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"
@ -27,6 +27,7 @@
#include "mu-maildir.hh" #include "mu-maildir.hh"
using namespace Mu; using namespace Mu;
using namespace Mu::Message;
static void static void
add_prop_nonempty(Sexp::List& list, const char* elm, const GSList* str_lst) add_prop_nonempty(Sexp::List& list, const char* elm, const GSList* str_lst)
@ -94,13 +95,13 @@ add_list_post(Sexp::List& list, MuMsg* msg)
static void static void
add_contacts(Sexp::List& list, MuMsg* msg) add_contacts(Sexp::List& list, MuMsg* msg)
{ {
using ContactPair = std::pair<MessageContact::Type, std::string_view>; using ContactPair = std::pair<Field::Id, std::string_view>;
constexpr std::array<ContactPair, 5> contact_types = {{ constexpr std::array<ContactPair, 5> contact_types = {{
{ MessageContact::Type::From, ":from" }, { Field::Id::From, ":from" },
{ MessageContact::Type::To, ":to" }, { Field::Id::To, ":to" },
{ MessageContact::Type::Cc, ":cc" }, { Field::Id::Cc, ":cc" },
{ MessageContact::Type::ReplyTo, ":reply-to" }, // { Field::Id::ReplyTo, ":reply-to" },
{ MessageContact::Type::Bcc, ":bcc" }, { Field::Id::Bcc, ":bcc" },
}}; }};
for (auto&& contact_type : contact_types) { for (auto&& contact_type : contact_types) {

View File

@ -624,40 +624,40 @@ get_all_contacts(MuMsg *self)
{ {
MessageContacts contacts; MessageContacts contacts;
for (auto&& mtype : { MessageContact::Type::From, MessageContact::Type::To, message_field_for_each([&](const auto& field){
MessageContact::Type::Cc, MessageContact::Type::ReplyTo, if (!field.is_contact())
MessageContact::Type::Bcc}) { return;
auto type_contacts{mu_msg_get_contacts(self, mtype)}; auto type_contacts{mu_msg_get_contacts(self, field.id)};
contacts.reserve(contacts.size() + type_contacts.size()); contacts.reserve(contacts.size() + type_contacts.size());
contacts.insert(contacts.end(), type_contacts.begin(), type_contacts.end()); contacts.insert(contacts.end(), type_contacts.begin(),
} type_contacts.end());
});
return contacts; return contacts;
} }
Mu::MessageContacts Mu::MessageContacts
Mu::mu_msg_get_contacts(MuMsg *self, MessageContact::Type mtype) Mu::mu_msg_get_contacts(MuMsg *self, std::optional<MessageField::Id> field_id)
{ {
typedef const char*(*AddressFunc)(MuMsg*); typedef const char*(*AddressFunc)(MuMsg*);
using AddressInfo = std::pair<GMimeAddressType, AddressFunc>; using AddressInfo = std::pair<GMimeAddressType, AddressFunc>;
g_return_val_if_fail(self, MessageContacts{}); g_return_val_if_fail(self, MessageContacts{});
g_return_val_if_fail(!field_id || message_field(*field_id).is_contact(),
if (mtype == MessageContact::Type::Unknown) MessageContacts{});
if (!field_id)
return get_all_contacts(self); return get_all_contacts(self);
const auto info = std::invoke([&]()->AddressInfo { const auto info = std::invoke([&]()->AddressInfo {
switch (mtype) { switch (*field_id) {
case MessageContact::Type::From: case MessageField::Id::From:
return { GMIME_ADDRESS_TYPE_FROM, mu_msg_get_from }; return { GMIME_ADDRESS_TYPE_FROM, mu_msg_get_from };
case MessageContact::Type::To: case MessageField::Id::To:
return { GMIME_ADDRESS_TYPE_TO, mu_msg_get_to }; return { GMIME_ADDRESS_TYPE_TO, mu_msg_get_to };
case MessageContact::Type::Cc: case MessageField::Id::Cc:
return { GMIME_ADDRESS_TYPE_CC, mu_msg_get_cc }; return { GMIME_ADDRESS_TYPE_CC, mu_msg_get_cc };
case MessageContact::Type::ReplyTo: case MessageField::Id::Bcc:
return { GMIME_ADDRESS_TYPE_REPLY_TO, {} };
case MessageContact::Type::Bcc:
return { GMIME_ADDRESS_TYPE_BCC, mu_msg_get_bcc }; return { GMIME_ADDRESS_TYPE_BCC, mu_msg_get_bcc };
default: default:
throw std::logic_error("bug"); throw std::logic_error("bug");
@ -668,10 +668,10 @@ Mu::mu_msg_get_contacts(MuMsg *self, MessageContact::Type mtype)
if (self->_file) { if (self->_file) {
if (auto&& lst{g_mime_message_get_addresses( if (auto&& lst{g_mime_message_get_addresses(
self->_file->_mime_msg, info.first)}; lst) self->_file->_mime_msg, info.first)}; lst)
return make_message_contacts(lst, mtype, mdate); return make_message_contacts(lst, *field_id, mdate);
} else if (info.second) { } else if (info.second) {
if (auto&& lst_str{info.second(self)}; lst_str) if (auto&& lst_str{info.second(self)}; lst_str)
return make_message_contacts(lst_str, mtype, mdate); return make_message_contacts(lst_str, *field_id, mdate);
} }
return {}; return {};

View File

@ -441,13 +441,12 @@ bool mu_msg_move_to_maildir(MuMsg* msg,
* Get a sequence with contacts of the given type for this message. * Get a sequence with contacts of the given type for this message.
* *
* @param msg a valid MuMsg* instance * @param msg a valid MuMsg* instance
* @param mtype the contact type; with Type::Unknown, get _all_ types. * @param field_id the contact field or none; if none get _all_ contact types.
* *
* @return a sequence * @return a sequence
*/ */
Mu::MessageContacts mu_msg_get_contacts (MuMsg *self, Mu::MessageContacts mu_msg_get_contacts (MuMsg *self,
MessageContact::Type mtype=MessageContact::Type::Unknown); std::optional<MessageField::Id> field_id={});
/** /**
* create a 'display contact' from an email header To/Cc/Bcc/From-type address * create a 'display contact' from an email header To/Cc/Bcc/From-type address
* ie., turn * ie., turn