# HG changeset patch
# Node ID b67583622d6e17edd62aef552231826e4159a48e
# Parent  5543556bfb085e267c67a25d0f81fa1abe1b1307
diff --git a/libpurple/purpleconversationmember.c b/libpurple/purpleconversationmember.c
--- a/libpurple/purpleconversationmember.c
+++ b/libpurple/purpleconversationmember.c
@@ -500,3 +500,28 @@
 
 	return purple_contact_info_get_name_for_display(member->contact_info);
 }
+
+gboolean
+purple_conversation_member_matches(PurpleConversationMember *member,
+                                   const char *needle)
+{
+	g_return_val_if_fail(PURPLE_IS_CONVERSATION_MEMBER(member), FALSE);
+
+	if(purple_strempty(needle)) {
+		return TRUE;
+	}
+
+	if(!purple_strempty(member->alias)) {
+		if(purple_strmatches(needle, member->alias)) {
+			return TRUE;
+		}
+	}
+
+	if(!purple_strempty(member->nickname)) {
+		if(purple_strmatches(needle, member->nickname)) {
+			return TRUE;
+		}
+	}
+
+	return purple_contact_info_matches(member->contact_info, needle);
+}
diff --git a/libpurple/purpleconversationmember.h b/libpurple/purpleconversationmember.h
--- a/libpurple/purpleconversationmember.h
+++ b/libpurple/purpleconversationmember.h
@@ -243,6 +243,25 @@
 PURPLE_AVAILABLE_IN_3_0
 const char *purple_conversation_member_get_name_for_display(PurpleConversationMember *member);
 
+/**
+ * purple_conversation_member_matches:
+ * @needle: (nullable): the string to match on
+ *
+ * Checks if a member matches a string.
+ *
+ * This uses [func@strmatches] to check the [property@ConversationMember:alias]
+ * and [property@ConversationMember:nickname] properties in order. If they
+ * don't match, the value of [method@ContactInfo.matches] will be returned.
+ *
+ * If @needle is %NULL or empty string, %TRUE will be returned.
+ *
+ * Returns: %TRUE if the member matches @needle in any way.
+ *
+ * Since: 3.0
+ */
+PURPLE_AVAILABLE_IN_3_0
+gboolean purple_conversation_member_matches(PurpleConversationMember *member, const char *needle);
+
 G_END_DECLS
 
 #endif /* PURPLE_CONVERSATION_MEMBER_H */
diff --git a/libpurple/tests/test_conversation_member.c b/libpurple/tests/test_conversation_member.c
--- a/libpurple/tests/test_conversation_member.c
+++ b/libpurple/tests/test_conversation_member.c
@@ -266,6 +266,85 @@
 }
 
 /******************************************************************************
+ * Matches Tests
+ *****************************************************************************/
+static void
+test_purple_conversation_member_matches_accepts_null(void) {
+	PurpleContactInfo *info = NULL;
+	PurpleConversationMember *member = NULL;
+
+	info = purple_contact_info_new(NULL);
+	member = purple_conversation_member_new(info);
+
+	g_assert_true(purple_conversation_member_matches(member, NULL));
+
+	g_assert_finalize_object(member);
+	g_assert_finalize_object(info);
+}
+
+static void
+test_purple_conversation_member_matches_empty_string(void) {
+	PurpleContactInfo *info = NULL;
+	PurpleConversationMember *member = NULL;
+
+	info = purple_contact_info_new(NULL);
+	member = purple_conversation_member_new(info);
+
+	g_assert_true(purple_conversation_member_matches(member, ""));
+
+	g_assert_finalize_object(member);
+	g_assert_finalize_object(info);
+}
+
+static void
+test_purple_conversation_member_matches_alias(void) {
+	PurpleContactInfo *info = NULL;
+	PurpleConversationMember *member = NULL;
+
+	info = purple_contact_info_new(NULL);
+	member = purple_conversation_member_new(info);
+	purple_conversation_member_set_alias(member, "this is the alias");
+
+	g_assert_true(purple_conversation_member_matches(member, "the"));
+	g_assert_false(purple_conversation_member_matches(member, "what"));
+
+	g_assert_finalize_object(member);
+	g_assert_finalize_object(info);
+}
+
+static void
+test_purple_conversation_member_matches_nickname(void) {
+	PurpleContactInfo *info = NULL;
+	PurpleConversationMember *member = NULL;
+
+	info = purple_contact_info_new(NULL);
+	member = purple_conversation_member_new(info);
+	purple_conversation_member_set_alias(member, "nickosaurus");
+
+	g_assert_true(purple_conversation_member_matches(member, "nick"));
+	g_assert_false(purple_conversation_member_matches(member, "dinosaur"));
+
+	g_assert_finalize_object(member);
+	g_assert_finalize_object(info);
+}
+
+static void
+test_purple_conversation_member_matches_contact_info(void) {
+	PurpleContactInfo *info = NULL;
+	PurpleConversationMember *member = NULL;
+
+	info = purple_contact_info_new(NULL);
+	purple_contact_info_set_alias(info, "something");
+	member = purple_conversation_member_new(info);
+
+	g_assert_true(purple_conversation_member_matches(member, "some"));
+	g_assert_false(purple_conversation_member_matches(member, "any"));
+
+	g_assert_finalize_object(member);
+	g_assert_finalize_object(info);
+}
+
+/******************************************************************************
  * Main
  *****************************************************************************/
 int
@@ -283,5 +362,17 @@
 	g_test_add_func("/conversation-member/typing-state/timeout",
 	                test_purple_conversation_member_typing_state_timeout);
 
+	g_test_add_func("/conversation-member/matches/accepts_null",
+	                test_purple_conversation_member_matches_accepts_null);
+	g_test_add_func("/conversation-member/matches/empty_string",
+	                test_purple_conversation_member_matches_empty_string);
+	g_test_add_func("/conversation-member/matches/alias",
+	                test_purple_conversation_member_matches_alias);
+	g_test_add_func("/conversation-member/matches/nickname",
+	                test_purple_conversation_member_matches_nickname);
+	g_test_add_func("/conversation-member/matches/contact_info",
+	                test_purple_conversation_member_matches_contact_info);
+
+
 	return g_test_run();
 }
