@@ -11,36 +11,23 @@ namespace Discord | |||||
/// <summary> | /// <summary> | ||||
/// A struct representing a forum channel tag. | /// A struct representing a forum channel tag. | ||||
/// </summary> | /// </summary> | ||||
public struct ForumTag : ISnowflakeEntity | |||||
public struct ForumTag : ISnowflakeEntity, IForumTag | |||||
{ | { | ||||
/// <summary> | /// <summary> | ||||
/// Gets the Id of the tag. | /// Gets the Id of the tag. | ||||
/// </summary> | /// </summary> | ||||
public ulong Id { get; } | public ulong Id { get; } | ||||
/// <summary> | |||||
/// Gets the name of the tag. | |||||
/// </summary> | |||||
/// <inheritdoc/> | |||||
public string Name { get; } | public string Name { get; } | ||||
/// <summary> | |||||
/// Gets the emoji of the tag or <see langword="null"/> if none is set. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// If the emoji is <see cref="Emote"/> only the <see cref="Emote.Id"/> will be populated. | |||||
/// Use <see cref="IGuild.GetEmoteAsync"/> to get the emoji. | |||||
/// </remarks> | |||||
/// <inheritdoc/> | |||||
public IEmote? Emoji { get; } | public IEmote? Emoji { get; } | ||||
/// <summary> | |||||
/// Gets whether this tag can only be added to or removed from threads by a member | |||||
/// with the <see cref="GuildPermissions.ManageThreads"/> permission | |||||
/// </summary> | |||||
/// <inheritdoc/> | |||||
public bool IsModerated { get; } | public bool IsModerated { get; } | ||||
/// <summary> | |||||
/// Gets when the tag was created. | |||||
/// </summary> | |||||
/// <inheritdoc/> | |||||
public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id); | public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id); | ||||
internal ForumTag(ulong id, string name, ulong? emojiId = null, string? emojiName = null, bool moderated = false) | internal ForumTag(ulong id, string name, ulong? emojiId = null, string? emojiName = null, bool moderated = false) | ||||
@@ -56,5 +43,25 @@ namespace Discord | |||||
Name = name; | Name = name; | ||||
IsModerated = moderated; | IsModerated = moderated; | ||||
} | } | ||||
public override int GetHashCode() => (Id, Name, Emoji, IsModerated).GetHashCode(); | |||||
public override bool Equals(object? obj) | |||||
=> obj is ForumTag tag && Equals(tag); | |||||
/// <summary> | |||||
/// Gets whether supplied tag is equals to the current one. | |||||
/// </summary> | |||||
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); | |||||
} | } | ||||
} | } |
@@ -8,12 +8,25 @@ public class ForumTagBuilder | |||||
private string? _name; | private string? _name; | ||||
private IEmote? _emoji; | private IEmote? _emoji; | ||||
private bool _moderated; | private bool _moderated; | ||||
private ulong? _id; | |||||
/// <summary> | /// <summary> | ||||
/// Returns the maximum length of name allowed by Discord. | /// Returns the maximum length of name allowed by Discord. | ||||
/// </summary> | /// </summary> | ||||
public const int MaxNameLength = 20; | public const int MaxNameLength = 20; | ||||
/// <summary> | |||||
/// Gets or sets the snowflake Id of the tag. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// If set this will update existing tag or will create a new one otherwise. | |||||
/// </remarks> | |||||
public ulong? Id | |||||
{ | |||||
get { return _id; } | |||||
set { _id = value; } | |||||
} | |||||
/// <summary> | /// <summary> | ||||
/// Gets or sets the name of the tag. | /// Gets or sets the name of the tag. | ||||
/// </summary> | /// </summary> | ||||
@@ -50,7 +63,7 @@ public class ForumTagBuilder | |||||
/// <summary> | /// <summary> | ||||
/// Initializes a new <see cref="ForumTagBuilder"/> class. | /// Initializes a new <see cref="ForumTagBuilder"/> class. | ||||
/// </summary> | |||||
/// </summary> | |||||
public ForumTagBuilder() | public ForumTagBuilder() | ||||
{ | { | ||||
@@ -59,31 +72,48 @@ public class ForumTagBuilder | |||||
/// <summary> | /// <summary> | ||||
/// Initializes a new <see cref="ForumTagBuilder"/> class with values | /// Initializes a new <see cref="ForumTagBuilder"/> class with values | ||||
/// </summary> | /// </summary> | ||||
public ForumTagBuilder(string name) | |||||
/// <param name="id"> If set existing tag will be updated or a new one will be created otherwise.</param> | |||||
/// <param name="name"> Name of the tag.</param> | |||||
/// <param name="isModerated"> Sets whether this tag can only be added to or removed from threads by a member | |||||
/// with the <see cref="GuildPermissions.ManageThreads"/> permission. </param> | |||||
public ForumTagBuilder(string name, ulong? id = null, bool isModerated = false) | |||||
{ | { | ||||
Name = name; | Name = name; | ||||
IsModerated = false; | |||||
IsModerated = isModerated; | |||||
Id = id; | |||||
} | } | ||||
/// <summary> | /// <summary> | ||||
/// Initializes a new <see cref="ForumTagBuilder"/> class with values | /// Initializes a new <see cref="ForumTagBuilder"/> class with values | ||||
/// </summary> | /// </summary> | ||||
public ForumTagBuilder(string name, IEmote? emoji = null, bool moderated = false) | |||||
/// <param name="name"> Name of the tag.</param> | |||||
/// <param name="id"> If set existing tag will be updated or a new one will be created otherwise.</param> | |||||
/// <param name="emoji"> Display emoji of the tag.</param> | |||||
/// <param name="isModerated"> Sets whether this tag can only be added to or removed from threads by a member | |||||
/// with the <see cref="GuildPermissions.ManageThreads"/> permission. </param> | |||||
public ForumTagBuilder(string name, ulong? id = null, bool isModerated = false, IEmote? emoji = null) | |||||
{ | { | ||||
Name = name; | Name = name; | ||||
Emoji = emoji; | Emoji = emoji; | ||||
IsModerated = moderated; | |||||
IsModerated = isModerated; | |||||
Id = id; | |||||
} | } | ||||
/// <summary> | /// <summary> | ||||
/// Initializes a new <see cref="ForumTagBuilder"/> class with values | /// Initializes a new <see cref="ForumTagBuilder"/> class with values | ||||
/// </summary> | /// </summary> | ||||
public ForumTagBuilder(string name, ulong? emoteId = null, bool moderated = false) | |||||
/// /// <param name="name"> Name of the tag.</param> | |||||
/// <param name="id"> If set existing tag will be updated or a new one will be created otherwise.</param> | |||||
/// <param name="emoteId"> The id of custom Display emoji of the tag.</param> | |||||
/// <param name="isModerated"> Sets whether this tag can only be added to or removed from threads by a member | |||||
/// with the <see cref="GuildPermissions.ManageThreads"/> permission </param> | |||||
public ForumTagBuilder(string name, ulong? id = null, bool isModerated = false, ulong? emoteId = null) | |||||
{ | { | ||||
Name = name; | Name = name; | ||||
if(emoteId is not null) | if(emoteId is not null) | ||||
Emoji = new Emote(emoteId.Value, null, false); | Emoji = new Emote(emoteId.Value, null, false); | ||||
IsModerated = moderated; | |||||
IsModerated = isModerated; | |||||
Id = id; | |||||
} | } | ||||
/// <summary> | /// <summary> | ||||
@@ -108,6 +138,17 @@ public class ForumTagBuilder | |||||
return this; | return this; | ||||
} | } | ||||
/// <summary> | |||||
/// Sets the id of the tag. | |||||
/// </summary> | |||||
/// <param name="id"> If set existing tag will be updated or a new one will be created otherwise.</param> | |||||
/// <exception cref="ArgumentException">Name length must be less than or equal to <see cref="MaxNameLength"/>.</exception> | |||||
public ForumTagBuilder WithId(ulong? id) | |||||
{ | |||||
Id = id; | |||||
return this; | |||||
} | |||||
/// <summary> | /// <summary> | ||||
/// Sets the emoji of the tag. | /// Sets the emoji of the tag. | ||||
/// </summary> | /// </summary> | ||||
@@ -118,11 +159,33 @@ public class ForumTagBuilder | |||||
} | } | ||||
/// <summary> | /// <summary> | ||||
/// Sets the IsModerated of the tag. | |||||
/// Sets whether this tag can only be added to or removed from threads by a member | |||||
/// with the <see cref="GuildPermissions.ManageThreads"/> permission | |||||
/// </summary> | /// </summary> | ||||
public ForumTagBuilder WithModerated(bool moderated) | public ForumTagBuilder WithModerated(bool moderated) | ||||
{ | { | ||||
IsModerated = moderated; | IsModerated = moderated; | ||||
return this; | return this; | ||||
} | } | ||||
public override int GetHashCode() => base.GetHashCode(); | |||||
public override bool Equals(object? obj) | |||||
=> obj is ForumTagBuilder builder && Equals(builder); | |||||
/// <summary> | |||||
/// Gets whether supplied tag builder is equals to the current one. | |||||
/// </summary> | |||||
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); | |||||
} | } |
@@ -3,9 +3,9 @@ namespace Discord; | |||||
public static class ForumTagBuilderExtensions | public static class ForumTagBuilderExtensions | ||||
{ | { | ||||
public static ForumTagBuilder ToForumTagBuilder(this ForumTag tag) | 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) | 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); | |||||
} | } |
@@ -2,22 +2,20 @@ namespace Discord; | |||||
#nullable enable | #nullable enable | ||||
public class ForumTagProperties | |||||
public class ForumTagProperties : IForumTag | |||||
{ | { | ||||
/// <summary> | /// <summary> | ||||
/// Gets the name of the tag. | |||||
/// Gets the Id of the tag. | |||||
/// </summary> | /// </summary> | ||||
public ulong Id { get; } | |||||
/// <inheritdoc/> | |||||
public string Name { get; } | public string Name { get; } | ||||
/// <summary> | |||||
/// Gets the emoji of the tag or <see langword="null"/> if none is set. | |||||
/// </summary> | |||||
/// <inheritdoc/> | |||||
public IEmote? Emoji { get; } | public IEmote? Emoji { get; } | ||||
/// <summary> | |||||
/// Gets whether this tag can only be added to or removed from threads by a member | |||||
/// with the <see cref="GuildPermissions.ManageThreads"/> permission | |||||
/// </summary> | |||||
/// <inheritdoc/> | |||||
public bool IsModerated { get; } | public bool IsModerated { get; } | ||||
internal ForumTagProperties(string name, IEmote? emoji = null, bool isMmoderated = false) | internal ForumTagProperties(string name, IEmote? emoji = null, bool isMmoderated = false) | ||||
@@ -26,4 +24,25 @@ public class ForumTagProperties | |||||
Emoji = emoji; | Emoji = emoji; | ||||
IsModerated = isMmoderated; | IsModerated = isMmoderated; | ||||
} | } | ||||
public override int GetHashCode() => (Id, Name, Emoji, IsModerated).GetHashCode(); | |||||
public override bool Equals(object? obj) | |||||
=> obj is ForumTagProperties tag && Equals(tag); | |||||
/// <summary> | |||||
/// Gets whether supplied tag is equals to the current one. | |||||
/// </summary> | |||||
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); | |||||
} | } |
@@ -0,0 +1,29 @@ | |||||
namespace Discord; | |||||
#nullable enable | |||||
/// <summary> | |||||
/// Represents a Discord forum tag | |||||
/// </summary> | |||||
public interface IForumTag | |||||
{ | |||||
/// <summary> | |||||
/// Gets the name of the tag. | |||||
/// </summary> | |||||
string Name { get; } | |||||
/// <summary> | |||||
/// Gets the emoji of the tag or <see langword="null"/> if none is set. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// If the emoji is <see cref="Emote"/> only the <see cref="Emote.Id"/> will be populated. | |||||
/// Use <see cref="IGuild.GetEmoteAsync"/> to get the emoji. | |||||
/// </remarks> | |||||
IEmote? Emoji { get; } | |||||
/// <summary> | |||||
/// Gets whether this tag can only be added to or removed from threads by a member | |||||
/// with the <see cref="GuildPermissions.ManageThreads"/> permission | |||||
/// </summary> | |||||
bool IsModerated { get; } | |||||
} |
@@ -5,6 +5,8 @@ namespace Discord.API | |||||
[JsonObject(MemberSerialization = MemberSerialization.OptIn)] | [JsonObject(MemberSerialization = MemberSerialization.OptIn)] | ||||
internal class ForumTagParams | internal class ForumTagParams | ||||
{ | { | ||||
[JsonProperty("id")] | |||||
public Optional<ulong> Id { get; set; } | |||||
[JsonProperty("name")] | [JsonProperty("name")] | ||||
public string Name { get; set; } | public string Name { get; set; } | ||||