Skip to content

Commit e8fe1ca

Browse files
committed
add snowflake json converter to v4
1 parent fe0ecbe commit e8fe1ca

File tree

1 file changed

+36
-21
lines changed

1 file changed

+36
-21
lines changed

src/Bot/Entities/Snowflake.cs

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
using System.Globalization;
2+
using System.Text.Json.Serialization;
23

34
namespace Volte.Entities;
45

6+
57
public readonly record struct Snowflake(ulong Raw) : IComparable<Snowflake>, IComparable, IParsable<Snowflake>
68
{
79
public int CompareTo(Snowflake other) => Raw.CompareTo(other.Raw);
@@ -20,15 +22,16 @@ public int CompareTo(object obj)
2022

2123
public DateTimeOffset Date => SnowflakeUtils.FromSnowflake(Raw);
2224

25+
public override string ToString() => Raw.ToString();
2326
public static implicit operator Snowflake(ulong raw) => new(raw);
2427
public static implicit operator ulong(Snowflake snowflake) => snowflake.Raw;
2528
public static implicit operator Snowflake(DateTimeOffset dto) => FromDate(dto);
2629
public static implicit operator DateTimeOffset(Snowflake snowflake) => snowflake.Date;
2730
public static implicit operator Snowflake(DateTime dto) => FromDate(dto);
2831
public static implicit operator DateTime(Snowflake snowflake) => snowflake.Date.DateTime;
29-
32+
3033
public static Snowflake Zero { get; set; } = default;
31-
34+
3235
public static Snowflake FromDate(DateTimeOffset dto) => new(SnowflakeUtils.ToSnowflake(dto));
3336

3437
public static Snowflake? TryParse(string value, IFormatProvider formatProvider = null)
@@ -46,32 +49,44 @@ public int CompareTo(object obj)
4649

4750
return null;
4851
}
49-
50-
public static Snowflake Parse(string s, IFormatProvider provider) =>
51-
TryParse(s, provider, out var result)
52-
? result
53-
: throw new ArgumentException($"'{s}' did not contain a valid 64-bit unsigned integer or DateTimeOffset.");
52+
53+
public static Snowflake Parse(string s, IFormatProvider provider)
54+
=> TryParse(s, provider)
55+
?? throw new ArgumentException($"'{s}' did not contain a valid 64-bit unsigned integer or DateTimeOffset.");
5456

5557
public static bool TryParse(string s, IFormatProvider provider, out Snowflake result)
5658
{
57-
result = Zero;
58-
if (string.IsNullOrWhiteSpace(s))
59-
return false;
59+
var res = TryParse(s, provider);
60+
result = res ?? Zero;
6061

61-
// As number
62-
if (ulong.TryParse(s, NumberStyles.None, provider, out var number))
63-
{
64-
result = new Snowflake(number);
65-
return true;
66-
}
62+
return res.HasValue;
63+
}
6764

68-
// As date
69-
if (DateTimeOffset.TryParse(s, provider, DateTimeStyles.None, out var dto))
65+
public static bool TryParse(string s, out Snowflake result)
66+
{
67+
var res = TryParse(s);
68+
result = res ?? Zero;
69+
70+
return res.HasValue;
71+
}
72+
73+
public class JsonConverter : JsonConverter<Snowflake>
74+
{
75+
public override Snowflake Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
7076
{
71-
result = FromDate(dto);
72-
return true;
77+
switch (reader.TokenType)
78+
{
79+
case JsonTokenType.String:
80+
return Parse(reader.GetString()!, null);
81+
case JsonTokenType.Number:
82+
return new Snowflake(reader.GetUInt64());
83+
default:
84+
throw new InvalidOperationException(
85+
"Snowflake JSON value is expected to be a datetime/integer string or a raw integer. Prefer raw integers.");
86+
}
7387
}
7488

75-
return false;
89+
public override void Write(Utf8JsonWriter writer, Snowflake value, JsonSerializerOptions options)
90+
=> writer.WriteNumberValue(value.Raw);
7691
}
7792
}

0 commit comments

Comments
 (0)