diff --git a/src/Discord.Net.Core/Entities/ForumTags/ForumTag.cs b/src/Discord.Net.Core/Entities/ForumTags/ForumTag.cs index 0cbddcb7c..afdb99bf7 100644 --- a/src/Discord.Net.Core/Entities/ForumTags/ForumTag.cs +++ b/src/Discord.Net.Core/Entities/ForumTags/ForumTag.cs @@ -11,36 +11,23 @@ namespace Discord /// /// A struct representing a forum channel tag. /// - public struct ForumTag : ISnowflakeEntity + public struct ForumTag : ISnowflakeEntity, IForumTag { /// /// Gets the Id of the tag. /// public ulong Id { get; } - /// - /// Gets the name of the tag. - /// + /// public string Name { get; } - /// - /// Gets the emoji of the tag or if none is set. - /// - /// - /// If the emoji is only the will be populated. - /// Use to get the emoji. - /// + /// public IEmote? Emoji { get; } - /// - /// Gets whether this tag can only be added to or removed from threads by a member - /// with the permission - /// + /// public bool IsModerated { get; } - /// - /// Gets when the tag was created. - /// + /// public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id); internal ForumTag(ulong id, string name, ulong? emojiId = null, string? emojiName = null, bool moderated = false) @@ -56,5 +43,25 @@ namespace Discord Name = name; IsModerated = moderated; } + + public override int GetHashCode() => (Id, Name, Emoji, IsModerated).GetHashCode(); + + public override bool Equals(object? obj) + => obj is ForumTag tag && Equals(tag); + + /// + /// Gets whether supplied tag is equals to the current one. + /// + public bool Equals(ForumTag tag) + => Id == tag.Id && + Name == tag.Name && + (Emoji is Emoji emoji && tag.Emoji is Emoji otherEmoji && emoji.Equals(otherEmoji) || + Emoji is Emote emote && tag.Emoji is Emote otherEmote && emote.Equals(otherEmote)) && + IsModerated == tag.IsModerated; + + public static bool operator ==(ForumTag? left, ForumTag? right) + => left?.Equals(right) ?? right is null; + + public static bool operator !=(ForumTag? left, ForumTag? right) => !(left == right); } } diff --git a/src/Discord.Net.Core/Entities/ForumTags/ForumTagBuilder.cs b/src/Discord.Net.Core/Entities/ForumTags/ForumTagBuilder.cs index 1f4df5b9c..d8e881189 100644 --- a/src/Discord.Net.Core/Entities/ForumTags/ForumTagBuilder.cs +++ b/src/Discord.Net.Core/Entities/ForumTags/ForumTagBuilder.cs @@ -8,12 +8,25 @@ public class ForumTagBuilder private string? _name; private IEmote? _emoji; private bool _moderated; + private ulong? _id; /// /// Returns the maximum length of name allowed by Discord. /// public const int MaxNameLength = 20; + /// + /// Gets or sets the snowflake Id of the tag. + /// + /// + /// If set this will update existing tag or will create a new one otherwise. + /// + public ulong? Id + { + get { return _id; } + set { _id = value; } + } + /// /// Gets or sets the name of the tag. /// @@ -50,7 +63,7 @@ public class ForumTagBuilder /// /// Initializes a new class. - /// + /// public ForumTagBuilder() { @@ -59,31 +72,48 @@ public class ForumTagBuilder /// /// Initializes a new class with values /// - public ForumTagBuilder(string name) + /// If set existing tag will be updated or a new one will be created otherwise. + /// Name of the tag. + /// Sets whether this tag can only be added to or removed from threads by a member + /// with the permission. + public ForumTagBuilder(string name, ulong? id = null, bool isModerated = false) { Name = name; - IsModerated = false; + IsModerated = isModerated; + Id = id; } /// /// Initializes a new class with values /// - public ForumTagBuilder(string name, IEmote? emoji = null, bool moderated = false) + /// Name of the tag. + /// If set existing tag will be updated or a new one will be created otherwise. + /// Display emoji of the tag. + /// Sets whether this tag can only be added to or removed from threads by a member + /// with the permission. + public ForumTagBuilder(string name, ulong? id = null, bool isModerated = false, IEmote? emoji = null) { Name = name; Emoji = emoji; - IsModerated = moderated; + IsModerated = isModerated; + Id = id; } /// /// Initializes a new class with values /// - public ForumTagBuilder(string name, ulong? emoteId = null, bool moderated = false) + /// /// Name of the tag. + /// If set existing tag will be updated or a new one will be created otherwise. + /// The id of custom Display emoji of the tag. + /// Sets whether this tag can only be added to or removed from threads by a member + /// with the permission + public ForumTagBuilder(string name, ulong? id = null, bool isModerated = false, ulong? emoteId = null) { Name = name; if(emoteId is not null) Emoji = new Emote(emoteId.Value, null, false); - IsModerated = moderated; + IsModerated = isModerated; + Id = id; } /// @@ -108,6 +138,17 @@ public class ForumTagBuilder return this; } + /// + /// Sets the id of the tag. + /// + /// If set existing tag will be updated or a new one will be created otherwise. + /// Name length must be less than or equal to . + public ForumTagBuilder WithId(ulong? id) + { + Id = id; + return this; + } + /// /// Sets the emoji of the tag. /// @@ -118,11 +159,33 @@ public class ForumTagBuilder } /// - /// Sets the IsModerated of the tag. + /// Sets whether this tag can only be added to or removed from threads by a member + /// with the permission /// public ForumTagBuilder WithModerated(bool moderated) { IsModerated = moderated; return this; } + + public override int GetHashCode() => base.GetHashCode(); + + public override bool Equals(object? obj) + => obj is ForumTagBuilder builder && Equals(builder); + + /// + /// Gets whether supplied tag builder is equals to the current one. + /// + public bool Equals(ForumTagBuilder? builder) + => builder is not null && + Id == builder.Id && + Name == builder.Name && + (Emoji is Emoji emoji && builder.Emoji is Emoji otherEmoji && emoji.Equals(otherEmoji) || + Emoji is Emote emote && builder.Emoji is Emote otherEmote && emote.Equals(otherEmote)) && + IsModerated == builder.IsModerated; + + public static bool operator ==(ForumTagBuilder? left, ForumTagBuilder? right) + => left?.Equals(right) ?? right is null ; + + public static bool operator !=(ForumTagBuilder? left, ForumTagBuilder? right) => !(left == right); } diff --git a/src/Discord.Net.Core/Entities/ForumTags/ForumTagBuilderExtensions.cs b/src/Discord.Net.Core/Entities/ForumTags/ForumTagBuilderExtensions.cs index 5bf7d2b85..73a953fe6 100644 --- a/src/Discord.Net.Core/Entities/ForumTags/ForumTagBuilderExtensions.cs +++ b/src/Discord.Net.Core/Entities/ForumTags/ForumTagBuilderExtensions.cs @@ -3,9 +3,9 @@ namespace Discord; public static class ForumTagBuilderExtensions { public static ForumTagBuilder ToForumTagBuilder(this ForumTag tag) - => new ForumTagBuilder(tag.Name, tag.Emoji, tag.IsModerated); + => new ForumTagBuilder(tag.Name, tag.Id, tag.IsModerated, tag.Emoji); public static ForumTagBuilder ToForumTagBuilder(this ForumTagProperties tag) - => new ForumTagBuilder(tag.Name, tag.Emoji, tag.IsModerated); + => new ForumTagBuilder(tag.Name, tag.Id, tag.IsModerated, tag.Emoji); } diff --git a/src/Discord.Net.Core/Entities/ForumTags/ForumTagProperties.cs b/src/Discord.Net.Core/Entities/ForumTags/ForumTagProperties.cs index 2770438be..6ded49204 100644 --- a/src/Discord.Net.Core/Entities/ForumTags/ForumTagProperties.cs +++ b/src/Discord.Net.Core/Entities/ForumTags/ForumTagProperties.cs @@ -2,22 +2,20 @@ namespace Discord; #nullable enable -public class ForumTagProperties +public class ForumTagProperties : IForumTag { /// - /// Gets the name of the tag. + /// Gets the Id of the tag. /// + public ulong Id { get; } + + /// public string Name { get; } - /// - /// Gets the emoji of the tag or if none is set. - /// + /// public IEmote? Emoji { get; } - /// - /// Gets whether this tag can only be added to or removed from threads by a member - /// with the permission - /// + /// public bool IsModerated { get; } internal ForumTagProperties(string name, IEmote? emoji = null, bool isMmoderated = false) @@ -26,4 +24,25 @@ public class ForumTagProperties Emoji = emoji; IsModerated = isMmoderated; } + + public override int GetHashCode() => (Id, Name, Emoji, IsModerated).GetHashCode(); + + public override bool Equals(object? obj) + => obj is ForumTagProperties tag && Equals(tag); + + /// + /// Gets whether supplied tag is equals to the current one. + /// + public bool Equals(ForumTagProperties? tag) + => tag is not null && + Id == tag.Id && + Name == tag.Name && + (Emoji is Emoji emoji && tag.Emoji is Emoji otherEmoji && emoji.Equals(otherEmoji) || + Emoji is Emote emote && tag.Emoji is Emote otherEmote && emote.Equals(otherEmote)) && + IsModerated == tag.IsModerated; + + public static bool operator ==(ForumTagProperties? left, ForumTagProperties? right) + => left?.Equals(right) ?? right is null; + + public static bool operator !=(ForumTagProperties? left, ForumTagProperties? right) => !(left == right); } diff --git a/src/Discord.Net.Core/Entities/ForumTags/IForumTag.cs b/src/Discord.Net.Core/Entities/ForumTags/IForumTag.cs new file mode 100644 index 000000000..8b8b866b2 --- /dev/null +++ b/src/Discord.Net.Core/Entities/ForumTags/IForumTag.cs @@ -0,0 +1,29 @@ +namespace Discord; + +#nullable enable + +/// +/// Represents a Discord forum tag +/// +public interface IForumTag +{ + /// + /// Gets the name of the tag. + /// + string Name { get; } + + /// + /// Gets the emoji of the tag or if none is set. + /// + /// + /// If the emoji is only the will be populated. + /// Use to get the emoji. + /// + IEmote? Emoji { get; } + + /// + /// Gets whether this tag can only be added to or removed from threads by a member + /// with the permission + /// + bool IsModerated { get; } +} diff --git a/src/Discord.Net.Rest/API/Rest/ForumTagParams.cs b/src/Discord.Net.Rest/API/Rest/ForumTagParams.cs index 86f77816f..d86f33b52 100644 --- a/src/Discord.Net.Rest/API/Rest/ForumTagParams.cs +++ b/src/Discord.Net.Rest/API/Rest/ForumTagParams.cs @@ -5,6 +5,8 @@ namespace Discord.API [JsonObject(MemberSerialization = MemberSerialization.OptIn)] internal class ForumTagParams { + [JsonProperty("id")] + public Optional Id { get; set; } [JsonProperty("name")] public string Name { get; set; }