Skip to content
Open
25 changes: 25 additions & 0 deletions NetCord/JsonModels/JsonPartialRole.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System.ComponentModel;
using System.Text.Json.Serialization;

namespace NetCord.JsonModels;

/// <remarks>
/// This class is used when a role is returned in a context where not all properties are available, i.e. in <see cref="Rest.RestInvite"/>.
/// </remarks>
public class JsonPartialRole : JsonEntity
{
[JsonPropertyName("name")]
public string Name { get; set; }

[JsonPropertyName("position")]
public int Position { get; set; }

[JsonPropertyName("colors")]
public JsonRoleColors Colors { get; set; }

[JsonPropertyName("icon")]
public string? IconHash { get; set; }

[JsonPropertyName("unicode_emoji")]
public string? UnicodeEmoji { get; set; }
}
20 changes: 3 additions & 17 deletions NetCord/JsonModels/JsonRole.cs
Original file line number Diff line number Diff line change
@@ -1,27 +1,13 @@
using System.ComponentModel;
using System.Text.Json.Serialization;

namespace NetCord.JsonModels;

public class JsonRole : JsonEntity
public class JsonRole : JsonPartialRole
{
[JsonPropertyName("name")]
public string Name { get; set; }

[JsonPropertyName("colors")]
public JsonRoleColors Colors { get; set; }

[JsonPropertyName("hoist")]
public bool Hoist { get; set; }

[JsonPropertyName("icon")]
public string? IconHash { get; set; }

[JsonPropertyName("unicode_emoji")]
public string? UnicodeEmoji { get; set; }

[JsonPropertyName("position")]
public int Position { get; set; }

[JsonPropertyName("permissions")]
public Permissions Permissions { get; set; }

Expand Down
72 changes: 72 additions & 0 deletions NetCord/PartialRole.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using System.ComponentModel;

using NetCord.JsonModels;
using NetCord.Rest;

namespace NetCord;

/// <summary>
/// Represents a partial role.
/// </summary>
/// <remarks>
/// Useful for <see cref="Rest.RestInvite"/>.
/// </remarks>
public partial class PartialRole : ClientEntity, IJsonModel<JsonPartialRole>
{
JsonPartialRole IJsonModel<JsonPartialRole>.JsonModel => _jsonModel;
private readonly JsonPartialRole _jsonModel;

/// <summary>
/// The role's ID.
/// </summary>
public override ulong Id => _jsonModel.Id;

/// <summary>
/// The name of the role.
/// </summary>
public string Name => _jsonModel.Name;

/// <summary>
/// The role's colors.
/// </summary>
public RoleColors Colors { get; }

/// <summary>
/// The raw position of this role.
/// </summary>
/// <remarks>
/// Use <see cref="Position"/> to get a properly comparable and sortable position value.
/// </remarks>
public int RawPosition => _jsonModel.Position;

/// <summary>
/// The position of this role for sorting and comparing.
/// </summary>
public RolePosition Position => new(RawPosition, Id);

/// <summary>
/// The role's icon hash.
/// </summary>
public string? IconHash => _jsonModel.IconHash;

/// <summary>
/// The role's Unicode emoji.
/// </summary>
public string? UnicodeEmoji => _jsonModel.UnicodeEmoji;

/// <summary>
/// The ID of the guild this role belongs to.
/// </summary>
public ulong GuildId { get; }

public override string ToString() => $"<@&{Id}>";
Comment thread
jedrek0429 marked this conversation as resolved.

public PartialRole(JsonPartialRole jsonModel, ulong guildId, RestClient client) : base(client)
{
_jsonModel = jsonModel;

Colors = new(jsonModel.Colors);

GuildId = guildId;
}
}
2 changes: 1 addition & 1 deletion NetCord/Rest/JsonModels/JsonRestInvite.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public class JsonRestInvite
public InviteFlags? Flags { get; set; }

[JsonPropertyName("roles")]
public JsonRole[]? Roles { get; set; }
public JsonPartialRole[]? Roles { get; set; }

[JsonPropertyName("uses")]
public int? Uses { get; set; }
Expand Down
4 changes: 2 additions & 2 deletions NetCord/Rest/RestClient.Guild.cs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ public async Task<IReadOnlyList<Role>> ModifyGuildRolePositionsAsync(ulong guild
}

[GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))]
[GenerateAlias([typeof(Role)], nameof(Role.GuildId), nameof(Role.Id), TypeNameOverride = $"{nameof(Guild)}{nameof(Role)}")]
[GenerateAlias([typeof(PartialRole)], nameof(PartialRole.GuildId), nameof(PartialRole.Id), TypeNameOverride = $"{nameof(Guild)}{nameof(Role)}")]
public async Task<Role> ModifyGuildRoleAsync(ulong guildId, ulong roleId, Action<RoleOptions> action, RestRequestProperties? properties = null, CancellationToken cancellationToken = default)
{
RoleOptions obj = new();
Expand All @@ -207,7 +207,7 @@ public async Task<Role> ModifyGuildRoleAsync(ulong guildId, ulong roleId, Action
}

[GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))]
[GenerateAlias([typeof(Role)], nameof(Role.GuildId), nameof(Role.Id), TypeNameOverride = $"{nameof(Guild)}{nameof(Role)}")]
[GenerateAlias([typeof(PartialRole)], nameof(PartialRole.GuildId), nameof(PartialRole.Id), TypeNameOverride = $"{nameof(Guild)}{nameof(Role)}")]
public Task DeleteGuildRoleAsync(ulong guildId, ulong roleId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default)
=> SendRequestAsync(HttpMethod.Delete, $"/guilds/{guildId}/roles/{roleId}", null, new(guildId), properties, cancellationToken: cancellationToken);

Expand Down
4 changes: 2 additions & 2 deletions NetCord/Rest/RestInvite.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public partial class RestInvite : IInvite, IJsonModel<JsonModels.JsonRestInvite>

public InviteFlags? Flags => _jsonModel.Flags;

public IReadOnlyList<Role>? Roles { get; }
public IReadOnlyList<PartialRole>? Roles { get; }

// Metadata
public int? Uses => _jsonModel.Uses;
Expand Down Expand Up @@ -61,7 +61,7 @@ public RestInvite(JsonModels.JsonRestInvite jsonModel, RestClient client)
var guildId = Guild.Id;

if (jsonModel.Roles is { } roles)
Roles = roles.Select(role => new Role(role, guildId, client)).ToArray();
Roles = roles.Select(role => new PartialRole(role, guildId, client)).ToArray();
}

if (jsonModel.Channel is { } channel)
Expand Down
84 changes: 21 additions & 63 deletions NetCord/Role.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,100 +4,58 @@
namespace NetCord;

/// <summary>
/// Represents a role in a guild.
/// Represents a full role in a guild.
/// </summary>
public partial class Role : ClientEntity, IJsonModel<JsonRole>
public partial class Role : PartialRole, IJsonModel<JsonRole>
{
JsonRole IJsonModel<JsonRole>.JsonModel => _jsonModel;
private readonly JsonRole _jsonModel;

/// <summary>
/// The <see cref="Role"/>'s ID.
/// The role's ID.
/// </summary>
public override ulong Id => _jsonModel.Id;

/// <summary>
/// The name of the <see cref="Role"/>.
/// </summary>
public string Name => _jsonModel.Name;

/// <summary>
/// The <see cref="Role"/>'s colors.
/// </summary>
public RoleColors Colors { get; }

/// <summary>
/// Whether this <see cref="Role"/> causes users with it to be displayed in a separate section in the guild users list.
/// Whether this role causes users with it to be displayed in a separate section in the guild users list.
/// </summary>
public bool Hoist => _jsonModel.Hoist;

/// <summary>
/// The <see cref="Role"/>'s icon hash.
/// </summary>
public string? IconHash => _jsonModel.IconHash;

/// <summary>
/// The <see cref="Role"/>'s Unicode emoji.
/// </summary>
public string? UnicodeEmoji => _jsonModel.UnicodeEmoji;

/// <summary>
/// The raw position of this <see cref="Role"/>.
/// </summary>
/// <remarks>
/// Use <see cref="Position"/> to get a properly comparable and sortable position value.
/// </remarks>
public int RawPosition => _jsonModel.Position;

/// <summary>
/// The position of this <see cref="Role"/> for sorting and comparing.
/// </summary>
public RolePosition Position => new(RawPosition, Id);

/// <summary>
/// The permission bit set for this <see cref="Role"/>.
/// The permission bit set for this role.
/// </summary>
public Permissions Permissions => _jsonModel.Permissions;

/// <summary>
/// Whether this <see cref="Role"/> is managed by an integration.
/// Whether this role is managed by an integration.
/// </summary>
public bool Managed => _jsonModel.Managed;

/// <summary>
/// Whether this <see cref="Role"/> is mentionable.
/// Whether this role is mentionable.
/// </summary>
public bool Mentionable => _jsonModel.Mentionable;

/// <summary>
/// The tags this <see cref="Role"/> has.
/// The tags this role has.
/// </summary>
public RoleTags? Tags { get; }

/// <summary>
/// The <see cref="Role"/>'s flags combined as a bitfield.
/// The role's flags combined as a bitfield.
/// </summary>
public RoleFlags Flags => _jsonModel.Flags;

/// <summary>
/// The ID of the guild this <see cref="Role"/> belongs to.
/// </summary>
public ulong GuildId { get; }

public Role(JsonRole jsonModel, ulong guildId, RestClient client) : base(client)
public Role(JsonRole jsonModel, ulong guildId, RestClient client) : base(jsonModel, guildId, client)
{
_jsonModel = jsonModel;

Colors = new(jsonModel.Colors);

if (jsonModel.Tags is { } tags)
Tags = new(tags);

GuildId = guildId;
}

/// <summary>
/// Gets the <see cref="ImageUrl"/> of the <see cref="Role"/>'s icon.
/// Gets the <see cref="ImageUrl"/> of the role's icon.
/// </summary>
/// <param name="format">The format of the returned <see cref="ImageUrl"/>.</param>
/// <returns>An <see cref="ImageUrl"/> pointing to the role's icon. If the role does not have one set, returns <see langword="null"/>.</returns>
Expand All @@ -109,27 +67,27 @@ public Role(JsonRole jsonModel, ulong guildId, RestClient client) : base(client)
}

/// <summary>
/// Represents the colors of a <see cref="Role"/>.
/// Represents the colors of a role.
/// </summary>
public class RoleColors(JsonRoleColors jsonModel) : IJsonModel<JsonRoleColors>
{
JsonRoleColors IJsonModel<JsonRoleColors>.JsonModel => jsonModel;

/// <summary>
/// The primary color for the <see cref="Role"/>.
/// The primary color for the role.
/// </summary>
public Color PrimaryColor => jsonModel.PrimaryColor;

/// <summary>
/// The secondary color for the <see cref="Role"/>. This will make the role a gradient between the other provided colors.
/// The secondary color for the role. This will make the role a gradient between the other provided colors.
/// </summary>
/// <remarks>
/// Requires the guild to have the <c>ENHANCED_ROLE_COLORS</c> guild feature.
/// </remarks>
public Color? SecondaryColor => jsonModel.SecondaryColor;

/// <summary>
/// The tertiary color for the <see cref="Role"/>. This will turn the gradient into a holographic style.
/// The tertiary color for the role. This will turn the gradient into a holographic style.
/// </summary>
/// <remarks>
/// Requires the guild to have the <c>ENHANCED_ROLE_COLORS</c> guild feature.
Expand All @@ -138,19 +96,19 @@ public class RoleColors(JsonRoleColors jsonModel) : IJsonModel<JsonRoleColors>
}

/// <summary>
/// Represents the tags associated with a <see cref="Role"/>.
/// Represents the tags associated with a role.
/// </summary>
public class RoleTags(JsonRoleTags jsonModel) : IJsonModel<JsonRoleTags>
{
JsonRoleTags IJsonModel<JsonRoleTags>.JsonModel => jsonModel;

/// <summary>
/// The ID of the bot this <see cref="Role"/> belongs to.
/// The ID of the bot this role belongs to.
/// </summary>
public ulong? BotId => jsonModel.BotId;

/// <summary>
/// The ID of the integration this <see cref="Role"/> belongs to.
/// The ID of the integration this role belongs to.
/// </summary>
public ulong? IntegrationId => jsonModel.IntegrationId;

Expand All @@ -160,17 +118,17 @@ public class RoleTags(JsonRoleTags jsonModel) : IJsonModel<JsonRoleTags>
public bool IsPremiumSubscriber => jsonModel.IsPremiumSubscriber;

/// <summary>
/// The ID of this <see cref="Role"/>'s subscription SKU and listing.
/// The ID of this role's subscription SKU and listing.
/// </summary>
public ulong? SubscriptionListingId => jsonModel.SubscriptionListingId;

/// <summary>
/// Whether this <see cref="Role"/> is available for purchase.
/// Whether this role is available for purchase.
/// </summary>
public bool IsAvailableForPurchase => jsonModel.IsAvailableForPurchase;

/// <summary>
/// Whether this <see cref="Role"/> is a guild's linked role.
/// Whether this role is a guild's linked role.
/// </summary>
public bool GuildConnections => jsonModel.GuildConnections;
}