| @@ -29,7 +29,8 @@ | |||||
| <PackageReference Update="Microsoft.Extensions.Hosting" Version="5.0.0" /> | <PackageReference Update="Microsoft.Extensions.Hosting" Version="5.0.0" /> | ||||
| <PackageReference Update="Microsoft.Extensions.Options" Version="5.0.0" /> | <PackageReference Update="Microsoft.Extensions.Options" Version="5.0.0" /> | ||||
| <PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.0.0" /> | <PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.0.0" /> | ||||
| <PackageReference Update="System.IO.Pipelines" Version="5.0.0" /> | |||||
| <PackageReference Update="System.IO.Pipelines" Version="5.0.1" /> | |||||
| <PackageReference Update="System.Text.Json" Version="5.0.2" /> | |||||
| <PackageReference Update="xunit" Version="2.4.1" /> | <PackageReference Update="xunit" Version="2.4.1" /> | ||||
| <PackageReference Update="xunit.runner.visualstudio" Version="2.4.3" /> | <PackageReference Update="xunit.runner.visualstudio" Version="2.4.3" /> | ||||
| </ItemGroup> | </ItemGroup> | ||||
| @@ -1,19 +1,21 @@ | |||||
| | | ||||
| Microsoft Visual Studio Solution File, Format Version 12.00 | Microsoft Visual Studio Solution File, Format Version 12.00 | ||||
| # Visual Studio 15 | |||||
| VisualStudioVersion = 15.0.26124.0 | |||||
| # Visual Studio Version 16 | |||||
| VisualStudioVersion = 16.0.31229.75 | |||||
| MinimumVisualStudioVersion = 15.0.26124.0 | MinimumVisualStudioVersion = 15.0.26124.0 | ||||
| Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{CD5CFA4B-143E-4495-8BFD-AF419226CBE5}" | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{CD5CFA4B-143E-4495-8BFD-AF419226CBE5}" | ||||
| EndProject | EndProject | ||||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Discord.Net.Gateway", "src\Gateway\Discord.Net.Gateway.csproj", "{DAF502E3-CFE6-4243-8049-9A6157F42111}" | |||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Gateway", "src\Gateway\Discord.Net.Gateway.csproj", "{DAF502E3-CFE6-4243-8049-9A6157F42111}" | |||||
| EndProject | EndProject | ||||
| Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{6D7B7A29-83FE-44F2-85E1-7D44B061EA27}" | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{6D7B7A29-83FE-44F2-85E1-7D44B061EA27}" | ||||
| EndProject | EndProject | ||||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PingPong", "samples\PingPong\PingPong.csproj", "{54A6E396-5186-4D79-893B-6EFD1CF658CB}" | |||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PingPong", "samples\PingPong\PingPong.csproj", "{54A6E396-5186-4D79-893B-6EFD1CF658CB}" | |||||
| EndProject | EndProject | ||||
| Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{A47FC28E-1835-46C3-AFD5-7C048A43C157}" | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{A47FC28E-1835-46C3-AFD5-7C048A43C157}" | ||||
| EndProject | EndProject | ||||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Discord.Net.Gateway.UnitTests", "test\Gateway\Discord.Net.Gateway.UnitTests.csproj", "{7EC53EB6-6C15-4FD7-9B83-95F96025C14D}" | |||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Gateway.UnitTests", "test\Gateway\Discord.Net.Gateway.UnitTests.csproj", "{7EC53EB6-6C15-4FD7-9B83-95F96025C14D}" | |||||
| EndProject | |||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Models", "src\Models\Discord.Net.Models.csproj", "{564A2E82-CE92-42F6-9D4E-8CC09C5CDF17}" | |||||
| EndProject | EndProject | ||||
| Global | Global | ||||
| GlobalSection(SolutionConfigurationPlatforms) = preSolution | GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||
| @@ -24,9 +26,6 @@ Global | |||||
| Release|x64 = Release|x64 | Release|x64 = Release|x64 | ||||
| Release|x86 = Release|x86 | Release|x86 = Release|x86 | ||||
| EndGlobalSection | EndGlobalSection | ||||
| GlobalSection(SolutionProperties) = preSolution | |||||
| HideSolutionNode = FALSE | |||||
| EndGlobalSection | |||||
| GlobalSection(ProjectConfigurationPlatforms) = postSolution | GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||||
| {DAF502E3-CFE6-4243-8049-9A6157F42111}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | {DAF502E3-CFE6-4243-8049-9A6157F42111}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||||
| {DAF502E3-CFE6-4243-8049-9A6157F42111}.Debug|Any CPU.Build.0 = Debug|Any CPU | {DAF502E3-CFE6-4243-8049-9A6157F42111}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||
| @@ -64,10 +63,29 @@ Global | |||||
| {7EC53EB6-6C15-4FD7-9B83-95F96025C14D}.Release|x64.Build.0 = Release|Any CPU | {7EC53EB6-6C15-4FD7-9B83-95F96025C14D}.Release|x64.Build.0 = Release|Any CPU | ||||
| {7EC53EB6-6C15-4FD7-9B83-95F96025C14D}.Release|x86.ActiveCfg = Release|Any CPU | {7EC53EB6-6C15-4FD7-9B83-95F96025C14D}.Release|x86.ActiveCfg = Release|Any CPU | ||||
| {7EC53EB6-6C15-4FD7-9B83-95F96025C14D}.Release|x86.Build.0 = Release|Any CPU | {7EC53EB6-6C15-4FD7-9B83-95F96025C14D}.Release|x86.Build.0 = Release|Any CPU | ||||
| {564A2E82-CE92-42F6-9D4E-8CC09C5CDF17}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||||
| {564A2E82-CE92-42F6-9D4E-8CC09C5CDF17}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||||
| {564A2E82-CE92-42F6-9D4E-8CC09C5CDF17}.Debug|x64.ActiveCfg = Debug|Any CPU | |||||
| {564A2E82-CE92-42F6-9D4E-8CC09C5CDF17}.Debug|x64.Build.0 = Debug|Any CPU | |||||
| {564A2E82-CE92-42F6-9D4E-8CC09C5CDF17}.Debug|x86.ActiveCfg = Debug|Any CPU | |||||
| {564A2E82-CE92-42F6-9D4E-8CC09C5CDF17}.Debug|x86.Build.0 = Debug|Any CPU | |||||
| {564A2E82-CE92-42F6-9D4E-8CC09C5CDF17}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||||
| {564A2E82-CE92-42F6-9D4E-8CC09C5CDF17}.Release|Any CPU.Build.0 = Release|Any CPU | |||||
| {564A2E82-CE92-42F6-9D4E-8CC09C5CDF17}.Release|x64.ActiveCfg = Release|Any CPU | |||||
| {564A2E82-CE92-42F6-9D4E-8CC09C5CDF17}.Release|x64.Build.0 = Release|Any CPU | |||||
| {564A2E82-CE92-42F6-9D4E-8CC09C5CDF17}.Release|x86.ActiveCfg = Release|Any CPU | |||||
| {564A2E82-CE92-42F6-9D4E-8CC09C5CDF17}.Release|x86.Build.0 = Release|Any CPU | |||||
| EndGlobalSection | |||||
| GlobalSection(SolutionProperties) = preSolution | |||||
| HideSolutionNode = FALSE | |||||
| EndGlobalSection | EndGlobalSection | ||||
| GlobalSection(NestedProjects) = preSolution | GlobalSection(NestedProjects) = preSolution | ||||
| {DAF502E3-CFE6-4243-8049-9A6157F42111} = {CD5CFA4B-143E-4495-8BFD-AF419226CBE5} | {DAF502E3-CFE6-4243-8049-9A6157F42111} = {CD5CFA4B-143E-4495-8BFD-AF419226CBE5} | ||||
| {54A6E396-5186-4D79-893B-6EFD1CF658CB} = {6D7B7A29-83FE-44F2-85E1-7D44B061EA27} | {54A6E396-5186-4D79-893B-6EFD1CF658CB} = {6D7B7A29-83FE-44F2-85E1-7D44B061EA27} | ||||
| {7EC53EB6-6C15-4FD7-9B83-95F96025C14D} = {A47FC28E-1835-46C3-AFD5-7C048A43C157} | {7EC53EB6-6C15-4FD7-9B83-95F96025C14D} = {A47FC28E-1835-46C3-AFD5-7C048A43C157} | ||||
| {564A2E82-CE92-42F6-9D4E-8CC09C5CDF17} = {CD5CFA4B-143E-4495-8BFD-AF419226CBE5} | |||||
| EndGlobalSection | |||||
| GlobalSection(ExtensibilityGlobals) = postSolution | |||||
| SolutionGuid = {36B0BFC9-AF79-4D25-89D4-2EE3C961612B} | |||||
| EndGlobalSection | EndGlobalSection | ||||
| EndGlobal | EndGlobal | ||||
| @@ -0,0 +1,58 @@ | |||||
| using System.Text.Json.Serialization; | |||||
| namespace Discord.Net.Models | |||||
| { | |||||
| /// <summary> | |||||
| /// Represents an audit entry info object. | |||||
| /// </summary> | |||||
| public record AuditEntryInfo | |||||
| { | |||||
| /// <summary> | |||||
| /// Number of days after which inactive members were kicked. | |||||
| /// </summary> | |||||
| [JsonPropertyName("delete_member_days")] | |||||
| public Optional<int> DeleteMemberDays { get; init; } // actually sent as Optional<string> | |||||
| /// <summary> | |||||
| /// Number of members removed by the prune. | |||||
| /// </summary> | |||||
| [JsonPropertyName("members_removed")] | |||||
| public Optional<int> MembersRemoved { get; init; } // actually sent as Optional<string> | |||||
| /// <summary> | |||||
| /// Channel in which the entities were targeted. | |||||
| /// </summary> | |||||
| [JsonPropertyName("channel_id")] | |||||
| public Optional<Snowflake> ChannelId { get; init; } | |||||
| /// <summary> | |||||
| /// Id of the message that was targeted. | |||||
| /// </summary> | |||||
| [JsonPropertyName("message_id")] | |||||
| public Optional<Snowflake> MessageId { get; init; } | |||||
| /// <summary> | |||||
| /// Number of entities that were targeted. | |||||
| /// </summary> | |||||
| [JsonPropertyName("count")] | |||||
| public Optional<int> Count { get; init; } // actually sent as Optional<string> | |||||
| /// <summary> | |||||
| /// Id of the overwritten entity. | |||||
| /// </summary> | |||||
| [JsonPropertyName("id")] | |||||
| public Optional<Snowflake> Id { get; init; } | |||||
| /// <summary> | |||||
| /// Type of overwritten entity - "0" for "role" or "1" for "member". | |||||
| /// </summary> | |||||
| [JsonPropertyName("type")] | |||||
| public Optional<AuditEntryInfo> Type { get; init; } // actually sent as Optional<string> | |||||
| /// <summary> | |||||
| /// Name of the role if type is "0" (not present if type is "1"). | |||||
| /// </summary> | |||||
| [JsonPropertyName("role_name")] | |||||
| public Optional<string> RoleName { get; init; } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,17 @@ | |||||
| namespace Discord.Net.Models | |||||
| { | |||||
| /// <summary> | |||||
| /// Represents type of the overwritten entity for an audit entry info. | |||||
| /// </summary> | |||||
| public enum AuditEntryInfoType | |||||
| { | |||||
| /// <summary> | |||||
| /// The type of the overwritten entity is a role. | |||||
| /// </summary> | |||||
| Role = 0, | |||||
| /// <summary> | |||||
| /// The type of the overwritten entity is a member. | |||||
| /// </summary> | |||||
| Member = 1, | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,34 @@ | |||||
| using System.Text.Json.Serialization; | |||||
| namespace Discord.Net.Models | |||||
| { | |||||
| /// <summary> | |||||
| /// Represents a discord audit log object. | |||||
| /// </summary> | |||||
| public record AuditLog | |||||
| { | |||||
| /// <summary> | |||||
| /// Gets an array of <see cref="Webhook"/>s. | |||||
| /// </summary> | |||||
| /*[JsonPropertyName("webhooks")] | |||||
| public Optional<Webhook[]> Webhooks { get; init; }*/ //TODO Add Webhook | |||||
| /// <summary> | |||||
| /// Gets an array of <see cref="User"/>s. | |||||
| /// </summary> | |||||
| /*[JsonPropertyName("users")] | |||||
| public Optional<User[]> Users { get; init; }*/ //TODO Add User | |||||
| /// <summary> | |||||
| /// Gets an array of <see cref="AuditLogEntry"/>s. | |||||
| /// </summary> | |||||
| [JsonPropertyName("audit_log_entries")] | |||||
| public Optional<AuditLogEntry[]> AuditLogEntries { get; init; } | |||||
| /// <summary> | |||||
| /// Gets an array of <see cref="Integration"/>s. | |||||
| /// </summary> | |||||
| /*[JsonPropertyName("integrations")] | |||||
| public Optional<Integration[]> Integrations { get; init; }*/ //TODO Add Integration | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,28 @@ | |||||
| using System.Text.Json.Serialization; | |||||
| namespace Discord.Net.Models | |||||
| { | |||||
| /// <summary> | |||||
| /// Represents an audit log change object. | |||||
| /// </summary> | |||||
| public record AuditLogChange | |||||
| { | |||||
| /// <summary> | |||||
| /// New value of the key. | |||||
| /// </summary> | |||||
| [JsonPropertyName("new_value")] | |||||
| public Optional<object> NewValue { get; init; } | |||||
| /// <summary> | |||||
| /// Old value of the key. | |||||
| /// </summary> | |||||
| [JsonPropertyName("old_value")] | |||||
| public Optional<object> OldValue { get; init; } | |||||
| /// <summary> | |||||
| /// Name of the audit log change key. | |||||
| /// </summary> | |||||
| [JsonPropertyName("key")] | |||||
| public string? Key { get; init; } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,52 @@ | |||||
| using System.Text.Json.Serialization; | |||||
| namespace Discord.Net.Models | |||||
| { | |||||
| /// <summary> | |||||
| /// Represents an audit log entry object. | |||||
| /// </summary> | |||||
| public record AuditLogEntry | |||||
| { | |||||
| /// <summary> | |||||
| /// Id of the affected entity (webhook, user, role, etc.). | |||||
| /// </summary> | |||||
| [JsonPropertyName("target_id")] | |||||
| public Snowflake? TargetId { get; init; } | |||||
| /// <summary> | |||||
| /// Changes made to the <see cref="TargetId"/>. | |||||
| /// </summary> | |||||
| [JsonPropertyName("changes")] | |||||
| public Optional<AuditLogChange[]> Changes { get; init; } | |||||
| /// <summary> | |||||
| /// The user who made the changes. | |||||
| /// </summary> | |||||
| [JsonPropertyName("user_id")] | |||||
| public Snowflake? UserId { get; init; } | |||||
| /// <summary> | |||||
| /// Id of the entry. | |||||
| /// </summary> | |||||
| [JsonPropertyName("id")] | |||||
| public Snowflake Id { get; init; } | |||||
| /// <summary> | |||||
| /// Type of action that occurred. | |||||
| /// </summary> | |||||
| [JsonPropertyName("action_type")] | |||||
| public AuditLogEvent ActionType { get; init; } | |||||
| /// <summary> | |||||
| /// Additional info for certain action types. | |||||
| /// </summary> | |||||
| [JsonPropertyName("options")] | |||||
| public Optional<AuditEntryInfo> Options { get; init; } | |||||
| /// <summary> | |||||
| /// The reason for the change (0-512 characters). | |||||
| /// </summary> | |||||
| [JsonPropertyName("reason")] | |||||
| public Optional<string> Reason { get; init; } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,153 @@ | |||||
| namespace Discord.Net.Models | |||||
| { | |||||
| /// <summary> | |||||
| /// Specifies the type of audit log event. | |||||
| /// </summary> | |||||
| public enum AuditLogEvent : int | |||||
| { | |||||
| /// <summary> | |||||
| /// Default value of this type. | |||||
| /// </summary> | |||||
| None = 0, | |||||
| /// <summary> | |||||
| /// The guild was updated. | |||||
| /// </summary> | |||||
| GuildUpdate = 1, | |||||
| /// <summary> | |||||
| /// A channel was created. | |||||
| /// </summary> | |||||
| ChannelCreate = 10, | |||||
| /// <summary> | |||||
| /// A channel was updated. | |||||
| /// </summary> | |||||
| ChannelUpdate = 11, | |||||
| /// <summary> | |||||
| /// A channel was deleted. | |||||
| /// </summary> | |||||
| ChannelDelete = 12, | |||||
| /// <summary> | |||||
| /// A channel overwrite was created. | |||||
| /// </summary> | |||||
| ChannelOverwriteCreate = 13, | |||||
| /// <summary> | |||||
| /// A channel overwrite was updated. | |||||
| /// </summary> | |||||
| ChannelOverwriteUpdate = 14, | |||||
| /// <summary> | |||||
| /// A channel overwrite was deleted. | |||||
| /// </summary> | |||||
| ChannelOverwriteDelete = 15, | |||||
| /// <summary> | |||||
| /// A guild member was kicked. | |||||
| /// </summary> | |||||
| MemberKick = 20, | |||||
| /// <summary> | |||||
| /// A guild member was pruned. | |||||
| /// </summary> | |||||
| MemberPrune = 21, | |||||
| /// <summary> | |||||
| /// A guild member was banned. | |||||
| /// </summary> | |||||
| MemberBanAdd = 22, | |||||
| /// <summary> | |||||
| /// A guild member was unbanned. | |||||
| /// </summary> | |||||
| MemberBanRemove = 23, | |||||
| /// <summary> | |||||
| /// A guild member was updated. | |||||
| /// </summary> | |||||
| MemberUpdate = 24, | |||||
| /// <summary> | |||||
| /// A guild role was updated. | |||||
| /// </summary> | |||||
| MemberRoleUpdate = 25, | |||||
| /// <summary> | |||||
| /// A guild member was moved. | |||||
| /// </summary> | |||||
| MemberMove = 26, | |||||
| /// <summary> | |||||
| /// A guild member was disconnected. | |||||
| /// </summary> | |||||
| MemberDisconnect = 27, | |||||
| /// <summary> | |||||
| /// A bot was added. | |||||
| /// </summary> | |||||
| BotAdd = 28, | |||||
| /// <summary> | |||||
| /// A role was created. | |||||
| /// </summary> | |||||
| RoleCreate = 30, | |||||
| /// <summary> | |||||
| /// A role was updated. | |||||
| /// </summary> | |||||
| RoleUpdate = 31, | |||||
| /// <summary> | |||||
| /// A role was deleted. | |||||
| /// </summary> | |||||
| RoleDelete = 32, | |||||
| /// <summary> | |||||
| /// An invite was created. | |||||
| /// </summary> | |||||
| InviteCreate = 40, | |||||
| /// <summary> | |||||
| /// An invite was updated. | |||||
| /// </summary> | |||||
| InviteUpdate = 41, | |||||
| /// <summary> | |||||
| /// An invite was deleted. | |||||
| /// </summary> | |||||
| InviteDelete = 42, | |||||
| /// <summary> | |||||
| /// A webhook was created. | |||||
| /// </summary> | |||||
| WebhookCreate = 50, | |||||
| /// <summary> | |||||
| /// A webhook was updated. | |||||
| /// </summary> | |||||
| WebhookUpdate = 51, | |||||
| /// <summary> | |||||
| /// A webhook was deleted. | |||||
| /// </summary> | |||||
| WebhookDelete = 52, | |||||
| /// <summary> | |||||
| /// An emoji was created. | |||||
| /// </summary> | |||||
| EmojiCreate = 60, | |||||
| /// <summary> | |||||
| /// An emoji was updated. | |||||
| /// </summary> | |||||
| EmojiUpdate = 61, | |||||
| /// <summary> | |||||
| /// An emoji was deleted. | |||||
| /// </summary> | |||||
| EmojiDelete = 62, | |||||
| /// <summary> | |||||
| /// A message was deleted. | |||||
| /// </summary> | |||||
| MessageDelete = 72, | |||||
| /// <summary> | |||||
| /// Message were deleted in bulk. | |||||
| /// </summary> | |||||
| MessageBulkDelete = 73, | |||||
| /// <summary> | |||||
| /// A message was pinned. | |||||
| /// </summary> | |||||
| MessagePin = 74, | |||||
| /// <summary> | |||||
| /// A message was unpinned. | |||||
| /// </summary> | |||||
| MessageUnpin = 75, | |||||
| /// <summary> | |||||
| /// An integration was created. | |||||
| /// </summary> | |||||
| IntegrationCreate = 80, | |||||
| /// <summary> | |||||
| /// An integration was updated. | |||||
| /// </summary> | |||||
| IntegrationUpdate = 81, | |||||
| /// <summary> | |||||
| /// An integration was deleted. | |||||
| /// </summary> | |||||
| IntegrationDelete = 82, | |||||
| } | |||||
| } | |||||
| @@ -8,5 +8,9 @@ | |||||
| Shared models between the Discord REST API and Gateway. | Shared models between the Discord REST API and Gateway. | ||||
| </Description> | </Description> | ||||
| </PropertyGroup> | </PropertyGroup> | ||||
| <ItemGroup> | |||||
| <PackageReference Include="System.Text.Json" /> | |||||
| </ItemGroup> | |||||
| </Project> | </Project> | ||||
| @@ -0,0 +1,98 @@ | |||||
| using System; | |||||
| namespace Discord.Net | |||||
| { | |||||
| /// <summary> | |||||
| /// Container to keep a type that might not be present. | |||||
| /// </summary> | |||||
| /// <typeparam name="T">Inner type</typeparam> | |||||
| public struct Optional<T> | |||||
| { | |||||
| private readonly T _value; | |||||
| /// <summary> | |||||
| /// Gets the inner value of this <see cref="Optional{T}"/> if present. | |||||
| /// </summary> | |||||
| /// <returns>The value inside this <see cref="Optional{T}"/>.</returns> | |||||
| /// <exception cref="InvalidOperationException">This <see cref="Optional{T}"/> has no inner value.</exception> | |||||
| public T Value => !IsSpecified ? throw new InvalidOperationException("This property has no value set.") : _value; | |||||
| /// <summary> | |||||
| /// Gets if this <see cref="Optional{T}"/> has an inner value. | |||||
| /// </summary> | |||||
| /// <returns>A boolean that determines if this <see cref="Optional{T}"/> has a <see cref="Value"/>.</returns> | |||||
| public bool IsSpecified { get; } | |||||
| private Optional(T value) | |||||
| { | |||||
| _value = value; | |||||
| IsSpecified = true; | |||||
| } | |||||
| /// <summary> | |||||
| /// Creates a new unspecified <see cref="Optional{T}"/>. | |||||
| /// </summary> | |||||
| /// <returns>An unspecified <see cref="Optional{T}"/>.</returns> | |||||
| public static Optional<T> Create() | |||||
| => default; | |||||
| /// <summary> | |||||
| /// Creates a new <see cref="Optional{T}"/> with the specified <paramref name="value"/>. | |||||
| /// </summary> | |||||
| /// <param name="value">Value that will be specified for this <see cref="Optional{T}"/>.</param> | |||||
| /// <returns>A specified <see cref="Optional{T}"/> with the provided value inside.</returns> | |||||
| public static Optional<T> Create(T value) | |||||
| => new(value); | |||||
| /// <summary> | |||||
| /// Gets the <see cref="Value"/> or their <see langword="default"/> value. | |||||
| /// </summary> | |||||
| /// <returns>The value inside this <see cref="Optional{T}"/> or their <see langword="default"/> value.</returns> | |||||
| public T GetValueOrDefault() | |||||
| => _value; | |||||
| /// <summary> | |||||
| /// Gets the <see cref="Value"/> or the default value provided. | |||||
| /// </summary> | |||||
| /// <returns>The value inside this <see cref="Optional{T}"/> or default value provided.</returns> | |||||
| public T GetValueOrDefault(T defaultValue) | |||||
| => IsSpecified ? _value : defaultValue; | |||||
| /// <inheritdoc/> | |||||
| public override bool Equals(object? other) | |||||
| { | |||||
| if (!IsSpecified) | |||||
| return other == null; | |||||
| if (other == null || _value == null) | |||||
| return false; | |||||
| return _value.Equals(other); | |||||
| } | |||||
| /// <inheritdoc/> | |||||
| public override int GetHashCode() | |||||
| => IsSpecified ? _value?.GetHashCode() ?? default : default; | |||||
| /// <summary> | |||||
| /// Returns the inner value ToString value or this type fully qualified name. | |||||
| /// </summary> | |||||
| /// <returns>The inner value string value or this type fully qualified name.</returns> | |||||
| public override string? ToString() | |||||
| => IsSpecified ? _value?.ToString() : default; | |||||
| /// <summary> | |||||
| /// Creates a new <see cref="Optional{T}"/> with the specified <paramref name="value"/>. | |||||
| /// </summary> | |||||
| /// <param name="value">Value to convert</param> | |||||
| /// <returns>A new <see cref="Optional{T}"/> with the specified <paramref name="value"/></returns> | |||||
| public static implicit operator Optional<T>(T value) | |||||
| => new(value); | |||||
| /// <summary> | |||||
| /// Gets the inner value. | |||||
| /// </summary> | |||||
| /// <param name="value">Value to convert</param> | |||||
| /// <returns>The inner value</returns> | |||||
| public static explicit operator T(Optional<T> value) | |||||
| => value.Value; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,76 @@ | |||||
| using System; | |||||
| namespace Discord.Net | |||||
| { | |||||
| /// <summary> | |||||
| /// Represents a discord snowflake. | |||||
| /// </summary> | |||||
| public struct Snowflake | |||||
| { | |||||
| private const ulong DiscordEpoch = 1420070400000UL; | |||||
| /// <summary> | |||||
| /// Gets the raw value of this snowflake. | |||||
| /// </summary> | |||||
| /// <returns>A <see cref="ulong"/> with the rae value.</returns> | |||||
| public ulong RawValue { get; } | |||||
| /// <summary> | |||||
| /// Creates a <see cref="Snowflake"/> based on the <paramref name="value"/> provided. | |||||
| /// </summary> | |||||
| /// <param name="value">Raw value of the snowflake.</param> | |||||
| public Snowflake(ulong value) | |||||
| { | |||||
| RawValue = value; | |||||
| } | |||||
| /// <summary> | |||||
| /// Creates a <see cref="Snowflake"/> based on the <paramref name="dateTimeOffset"/> provided. | |||||
| /// </summary> | |||||
| /// <param name="dateTimeOffset">DateTimeOffset of this snowflake.</param> | |||||
| public Snowflake(DateTimeOffset dateTimeOffset) | |||||
| { | |||||
| RawValue = ((ulong)dateTimeOffset.ToUniversalTime().ToUnixTimeMilliseconds() - DiscordEpoch) << 22; | |||||
| } | |||||
| /// <summary> | |||||
| /// Creates a <see cref="Snowflake"/> based on the <paramref name="dateTime"/> provided. | |||||
| /// </summary> | |||||
| /// <param name="dateTime">DateTime of this snowflake.</param> | |||||
| public Snowflake(DateTime dateTime) | |||||
| : this(new DateTimeOffset(dateTime)) { } | |||||
| /// <summary> | |||||
| /// Converts this <see cref="Snowflake"/> to a <see cref="DateTimeOffset"/>. | |||||
| /// </summary> | |||||
| /// <returns>A <see cref="DateTimeOffset"/> of this snowflake.</returns> | |||||
| public DateTimeOffset ToDateTimeOffset() => DateTimeOffset.FromUnixTimeMilliseconds((long)((RawValue >> 22) + DiscordEpoch)); | |||||
| /// <summary> | |||||
| /// Converts this <see cref="Snowflake"/> to a <see cref="DateTime"/>. | |||||
| /// </summary> | |||||
| /// <returns>A <see cref="DateTime"/> of this snowflake.</returns> | |||||
| public DateTimeOffset ToDateTime() => ToDateTimeOffset().UtcDateTime; | |||||
| /// <summary> | |||||
| /// Converts this <see cref="Snowflake"/> to a <see cref="ulong"/>. | |||||
| /// </summary> | |||||
| /// <param name="snowflake">Value that will be converted</param> | |||||
| /// <returns>A <see cref="ulong"/> with the raw value.</returns> | |||||
| public static implicit operator ulong(Snowflake snowflake) => snowflake.RawValue; | |||||
| /// <summary> | |||||
| /// Converts this <see cref="ulong"/> to a <see cref="Snowflake"/>. | |||||
| /// </summary> | |||||
| /// <param name="value">Value that will be converted</param> | |||||
| /// <returns>A <see cref="Snowflake"/> with <paramref name="value"/> as the raw value.</returns> | |||||
| public static implicit operator Snowflake(ulong value) => new Snowflake(value); | |||||
| /// <summary> | |||||
| /// Returns the raw value as <see cref="string"/>. | |||||
| /// </summary> | |||||
| /// <returns>A <see cref="string"/> that is the raw value.</returns> | |||||
| public override string ToString() | |||||
| => RawValue.ToString(); | |||||
| } | |||||
| } | |||||