@@ -29,7 +29,8 @@ | |||
<PackageReference Update="Microsoft.Extensions.Hosting" Version="5.0.0" /> | |||
<PackageReference Update="Microsoft.Extensions.Options" Version="5.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.runner.visualstudio" Version="2.4.3" /> | |||
</ItemGroup> | |||
@@ -1,19 +1,21 @@ | |||
| |||
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 | |||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{CD5CFA4B-143E-4495-8BFD-AF419226CBE5}" | |||
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 | |||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{6D7B7A29-83FE-44F2-85E1-7D44B061EA27}" | |||
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 | |||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{A47FC28E-1835-46C3-AFD5-7C048A43C157}" | |||
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 | |||
Global | |||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | |||
@@ -24,9 +26,6 @@ Global | |||
Release|x64 = Release|x64 | |||
Release|x86 = Release|x86 | |||
EndGlobalSection | |||
GlobalSection(SolutionProperties) = preSolution | |||
HideSolutionNode = FALSE | |||
EndGlobalSection | |||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | |||
{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 | |||
@@ -64,10 +63,29 @@ Global | |||
{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.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 | |||
GlobalSection(NestedProjects) = preSolution | |||
{DAF502E3-CFE6-4243-8049-9A6157F42111} = {CD5CFA4B-143E-4495-8BFD-AF419226CBE5} | |||
{54A6E396-5186-4D79-893B-6EFD1CF658CB} = {6D7B7A29-83FE-44F2-85E1-7D44B061EA27} | |||
{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 | |||
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. | |||
</Description> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<PackageReference Include="System.Text.Json" /> | |||
</ItemGroup> | |||
</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(); | |||
} | |||
} |