diff --git a/lib/message/mu-flags.cc b/lib/message/mu-flags.cc index bd3e57e6..4668cb61 100644 --- a/lib/message/mu-flags.cc +++ b/lib/message/mu-flags.cc @@ -105,10 +105,13 @@ test_flags_from_expr() (Flags::Flagged | Flags::Unread | Flags::HasAttachment | Flags::MailingList)); + /* note: unread is a special flag, _implied_ from "new or not seen" */ + static_assert(flags_from_absolute_expr("N").value() == (Flags::New|Flags::Unread)); + static_assert(!flags_from_absolute_expr("DRT?")); static_assert(flags_from_absolute_expr("DRT?", true/*ignore invalid*/).value() == (Flags::Draft | Flags::Replied | - Flags::Trashed)); + Flags::Trashed | Flags::Unread)); static_assert(flags_from_absolute_expr("DFPNxulabcdef", true/*ignore invalid*/).value() == (Flags::Draft|Flags::Flagged|Flags::Passed| Flags::New | Flags::Encrypted | @@ -126,6 +129,16 @@ test_flags_from_delta_expr() static_assert(flags_from_delta_expr( "+S-u-N", Flags::New|Flags::Unread).value() == Flags::Seen); + + /* note: unread is a special flag, _implied_ from "new or not seen" */ + static_assert(flags_from_delta_expr( + "+S-N", Flags::New|Flags::Unread).value() == + Flags::Seen); + static_assert(flags_from_delta_expr( + "-S", Flags::Seen).value() == + Flags::Unread); + + static_assert(flags_from_delta_expr("+R+P-F", Flags::Seen).value() == (Flags::Seen|Flags::Passed|Flags::Replied)); /* '-B' is invalid */ @@ -134,7 +147,7 @@ test_flags_from_delta_expr() static_assert(flags_from_delta_expr("+R+P-B", Flags::Seen, true) == (Flags::Replied|Flags::Passed|Flags::Seen)); static_assert(flags_from_delta_expr("+F+T-S", Flags::None, true).value() == - (Flags::Flagged|Flags::Trashed)); + (Flags::Flagged|Flags::Trashed|Flags::Unread)); } /* diff --git a/lib/message/mu-flags.hh b/lib/message/mu-flags.hh index 2ef1feb2..8675f00c 100644 --- a/lib/message/mu-flags.hh +++ b/lib/message/mu-flags.hh @@ -1,5 +1,5 @@ /* -** Copyright (C) 2022 Dirk-Jan C. Binnema +** Copyright (C) 2022-2023 Dirk-Jan C. Binnema ** ** 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 @@ -225,10 +225,27 @@ flag_info(std::string_view name) return Nothing; } +/** + * 'unread' is a pseudo-flag that means 'new or not seen' + * + * @param flags + * + * @return flags with unread added or removed. + */ +constexpr Flags +imply_unread(Flags flags) +{ + /* unread is a pseudo flag equivalent to 'new or not seen' */ + if (any_of(flags & Flags::New) || none_of(flags & Flags::Seen)) + return flags | Flags::Unread; + else + return flags & ~Flags::Unread; +} + /** * There are two string-based expression types for flags: * 1) 'absolute': replace the existing flags - * 2_ 'delta' : flags as a delta of existing flags. + * 2) 'delta' : flags as a delta of existing flags. */ /** @@ -253,7 +270,7 @@ flags_from_absolute_expr(std::string_view expr, bool ignore_invalid = false) flags |= info->flag; } - return flags; + return imply_unread(flags); } /** @@ -296,7 +313,8 @@ flags_from_delta_expr(std::string_view expr, Flags flags, } } - return flags; + return imply_unread(flags); + } /**