diff --git a/X10D.DSharpPlus/src/MentionUtility.cs b/X10D.DSharpPlus/src/MentionUtility.cs new file mode 100644 index 0000000..efda930 --- /dev/null +++ b/X10D.DSharpPlus/src/MentionUtility.cs @@ -0,0 +1,329 @@ +using System.Globalization; + +namespace X10D.DSharpPlus; + +/// +/// Provides methods for encoding and decoding Discord mention strings. +/// +/// +/// The implementations in this class are designed to resemble MentionUtils as provided by Discord.NET. The source is +/// available +/// +/// here +/// . +/// +public static class MentionUtility +{ + /// + /// Returns a channel mention string built from the specified channel ID. + /// + /// The ID of the channel to mention. + /// A channel mention string in the format <#123>. + public static string MentionChannel(decimal id) + { + return $"<#{id:N0}>"; + } + + /// + /// Returns a channel mention string built from the specified channel ID. + /// + /// The ID of the channel to mention. + /// A channel mention string in the format <#123>. + [CLSCompliant(false)] + public static string MentionChannel(ulong id) + { + return $"<#{id}>"; + } + + /// + /// Returns a role mention string built from the specified channel ID. + /// + /// The ID of the role to mention. + /// A role mention string in the format <@&123>. + public static string MentionRole(decimal id) + { + return $"<@&{id:N0}>"; + } + + /// + /// Returns a role mention string built from the specified role ID. + /// + /// The ID of the role to mention. + /// A role mention string in the format <@&123>. + [CLSCompliant(false)] + public static string MentionRole(ulong id) + { + return $"<@&{id}>"; + } + + /// + /// Returns a user mention string built from the specified user ID. + /// + /// The ID of the user to mention. + /// A user mention string in the format <@123>. + [CLSCompliant(false)] + public static string MentionUser(decimal id) + { + return MentionUser(id, false); + } + + /// + /// Returns a user mention string built from the specified user ID. + /// + /// The ID of the user to mention. + /// + /// if the mention string should account for nicknames; otherwise, . + /// + /// + /// A user mention string in the format <@!123> if is , + /// or in the format <@123> if is . + /// + [CLSCompliant(false)] + public static string MentionUser(decimal id, bool nickname) + { + return nickname ? $"<@!{id:N0}>" : $"<@{id:N0}>"; + } + + /// + /// Returns a user mention string built from the specified user ID. + /// + /// The ID of the user to mention. + /// A user mention string in the format <@123>. + [CLSCompliant(false)] + public static string MentionUser(ulong id) + { + return MentionUser(id, false); + } + + /// + /// Returns a user mention string built from the specified user ID. + /// + /// The ID of the user to mention. + /// + /// if the mention string should account for nicknames; otherwise, . + /// + /// + /// A user mention string in the format <@!123> if is , + /// or in the format <@123> if is . + /// + [CLSCompliant(false)] + public static string MentionUser(ulong id, bool nickname) + { + return nickname ? $"<@!{id}>" : $"<@{id}>"; + } + + /// + /// Parses a provided channel mention string to a decimal value representing the channel ID. A return value indicates + /// whether the parse succeeded. + /// + /// A string containing a mention string to parse, in the format <#123>. + /// + /// When this method returns, contains the decimal value representing the channel ID contained within + /// , if the conversion succeeded, or zero if the conversion failed. The conversion fails if the + /// parameter is or , is not of the correct + /// format, or represents a number less than or greater than . + /// + /// if the parse was successful; otherwise, . + public static bool TryParseChannel(string? value, out decimal result) + { + result = 0; + if (string.IsNullOrWhiteSpace(value)) + { + return false; + } + + if (value.Length < 3 || value[0] != '<' || value[1] != '#' || value[^1] != '>') + { + return false; + } + + value = value.Substring(2, value.Length - 3); // <#123> + if (!ulong.TryParse(value, NumberStyles.None, CultureInfo.InvariantCulture, out ulong actual)) + { + return false; + } + + result = actual; + return true; + } + + /// + /// Parses a provided channel mention string to a 64-bit unsigned integer representing the channel ID. A return value + /// indicates whether the parse succeeded. + /// + /// A string containing a mention string to parse, in the format <#123>. + /// + /// When this method returns, contains the 64-bit unsigned integer value representing the channel ID contained within + /// , if the conversion succeeded, or zero if the conversion failed. The conversion fails if the + /// parameter is or , is not of the correct + /// format, or represents a number less than or greater than . + /// + /// if the parse was successful; otherwise, . + [CLSCompliant(false)] + public static bool TryParseChannel(string? value, out ulong result) + { + result = 0; + if (string.IsNullOrWhiteSpace(value)) + { + return false; + } + + if (value.Length < 3 || value[0] != '<' || value[1] != '#' || value[^1] != '>') + { + return false; + } + + value = value.Substring(2, value.Length - 3); // <#123> + return ulong.TryParse(value, NumberStyles.None, CultureInfo.InvariantCulture, out result); + } + + /// + /// Parses a provided role mention string to a decimal value representing the role ID. A return value indicates whether + /// the parse succeeded. + /// + /// A string containing a mention string to parse, in the format <@&123>. + /// + /// When this method returns, contains the decimal value representing the role ID contained within + /// , if the conversion succeeded, or zero if the conversion failed. The conversion fails if the + /// parameter is or , is not of the correct + /// format, or represents a number less than or greater than . + /// + /// if the parse was successful; otherwise, . + public static bool TryParseRole(string? value, out decimal result) + { + result = 0; + if (string.IsNullOrWhiteSpace(value)) + { + return false; + } + + if (value.Length < 4 || value[0] != '<' || value[1] != '@' || value[2] != '&' || value[^1] != '>') + { + return false; + } + + value = value.Substring(3, value.Length - 4); // <@&123> + if (!ulong.TryParse(value, NumberStyles.None, CultureInfo.InvariantCulture, out ulong actual)) + { + return false; + } + + result = actual; + return true; + } + + /// + /// Parses a provided role mention string to a 64-bit unsigned integer representing the role ID. A return value indicates + /// whether the parse succeeded. + /// + /// A string containing a mention string to parse, in the format <@&123>. + /// + /// When this method returns, contains the 64-bit unsigned integer value representing the role ID contained within + /// , if the conversion succeeded, or zero if the conversion failed. The conversion fails if the + /// parameter is or , is not of the correct + /// format, or represents a number less than or greater than . + /// + /// if the parse was successful; otherwise, . + [CLSCompliant(false)] + public static bool TryParseRole(string? value, out ulong result) + { + result = 0; + if (string.IsNullOrWhiteSpace(value)) + { + return false; + } + + if (value.Length < 4 || value[0] != '<' || value[1] != '@' || value[2] != '&' || value[^1] != '>') + { + return false; + } + + value = value.Substring(3, value.Length - 4); // <@&123> + return ulong.TryParse(value, NumberStyles.None, CultureInfo.InvariantCulture, out result); + } + + /// + /// Parses a provided user mention string to a decimal value representing the user ID. A return value indicates whether + /// the parse succeeded. + /// + /// + /// A string containing a mention string to parse, in the format <@123> or <@!123>. + /// + /// + /// When this method returns, contains the decimal value representing the user ID contained within + /// , if the conversion succeeded, or zero if the conversion failed. The conversion fails if the + /// parameter is or , is not of the correct + /// format, or represents a number less than or greater than . + /// + /// if the parse was successful; otherwise, . + public static bool TryParseUser(string? value, out decimal result) + { + result = 0; + if (string.IsNullOrWhiteSpace(value)) + { + return false; + } + + if (value.Length < 3 || value[0] != '<' || value[1] != '@' || value[^1] != '>') + { + return false; + } + + if (value.Length >= 4 && value[2] == '!') + { + value = value.Substring(3, value.Length - 4); // <@!123> + } + else + { + value = value.Substring(2, value.Length - 3); // <@123> + } + + if (!ulong.TryParse(value, NumberStyles.None, CultureInfo.InvariantCulture, out ulong actual)) + { + return false; + } + + result = actual; + return true; + } + + /// + /// Parses a provided user mention string to a 64-bit unsigned integer representing the user ID. A return value indicates + /// whether the parse succeeded. + /// + /// + /// A string containing a mention string to parse, in the format <@123> or <@!123>. + /// + /// + /// When this method returns, contains the 64-bit unsigned integer value representing the user ID contained within + /// , if the conversion succeeded, or zero if the conversion failed. The conversion fails if the + /// parameter is or , is not of the correct + /// format, or represents a number less than or greater than . + /// + /// if the parse was successful; otherwise, . + [CLSCompliant(false)] + public static bool TryParseUser(string? value, out ulong result) + { + result = 0; + if (string.IsNullOrWhiteSpace(value)) + { + return false; + } + + if (value.Length < 3 || value[0] != '<' || value[1] != '@' || value[^1] != '>') + { + return false; + } + + if (value.Length >= 4 && value[2] == '!') + { + value = value.Substring(3, value.Length - 4); // <@!123> + } + else + { + value = value.Substring(2, value.Length - 3); // <@123> + } + + return ulong.TryParse(value, NumberStyles.None, CultureInfo.InvariantCulture, out result); + } +}