Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions src/FlakeId.Tests/ParseTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text.Json;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace FlakeId.Tests
Expand Down Expand Up @@ -73,5 +74,34 @@ public void Id_TryParse_Problematic()
{
Id id = Id.Parse(1108047973760811023);
}

public class IdJson
{
public required Id Id { get; set; }
}

[TestMethod]
public void Id_JsonConverter_Read()
{
const string json = "{\"Id\":1108047973760811023}";

var obj = JsonSerializer.Deserialize<IdJson>(json);

Assert.IsNotNull(obj);
Assert.AreEqual(1108047973760811023, obj.Id);
}

[TestMethod]
public void Id_JsonConverter_Write()
{
var obj = new IdJson
{
Id = Id.Parse(1108047973760811023)
};

string json = JsonSerializer.Serialize(obj);

Assert.AreEqual("{\"Id\":\"1108047973760811023\"}", json);
}
}
}
35 changes: 35 additions & 0 deletions src/FlakeId/Extensions/FlakeIdJsonConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace FlakeId.Extensions
{
public class FlakeIdJsonConverter : JsonConverter<Id>
{
public override Id Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.Number && reader.TryGetInt64(out long value))
{
return new Id(value);
}

if (reader.TokenType != JsonTokenType.String)
{
throw new JsonException("Invalid JSON token for FlakeId.Id");
}

string stringValue = reader.GetString();
if (stringValue != null && long.TryParse(stringValue, out long parsedValue))
{
return new Id(parsedValue);
}

throw new JsonException("Invalid JSON token for FlakeId.Id");
}

public override void Write(Utf8JsonWriter writer, Id value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString());
}
}
}
4 changes: 1 addition & 3 deletions src/FlakeId/Extensions/IdExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,9 @@ public static bool IsSnowflake(this Id id)
// The closest we can get is by decomposing its components, and ensuring all of them are set
// to values that would be valid for a snowflake.
long timestamp = id >> TimestampOffset;
long thread = (id >> ThreadOffset) & Id.ThreadIdMask;
long process = (id >> ProcessOffset) & Id.ProcessIdMask;
long increment = id & Id.IncrementMask;

return timestamp > 0 && thread > 0 && process > 0 && increment >= 0;
return timestamp > 0 && increment >= 0;
}

/// <summary>
Expand Down
5 changes: 4 additions & 1 deletion src/FlakeId/FlakeId.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.0;net9.0</TargetFrameworks>
<TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Description>Discord inspired, Twitter like implementation of Snowflake IDs, focused on performance. Snowflakes are 64 bit, highly optimized, decentralized, K-ordered, unique identifiers.</Description>
<RepositoryUrl>https://github.com/aevitas/flakeid</RepositoryUrl>
Expand Down Expand Up @@ -36,4 +36,7 @@
</None>
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="System.Text.Json" Version="8.0.5" />
</ItemGroup>
</Project>
2 changes: 2 additions & 0 deletions src/FlakeId/Id.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@
using System.Diagnostics;
using System.Threading;
using FlakeId.Extensions;
using System.Text.Json.Serialization;

namespace FlakeId
{
/// <summary>
/// Represents a unique, K-ordered, sortable identifier.
/// </summary>
[DebuggerDisplay("{_value}")]
[JsonConverter(typeof(FlakeIdJsonConverter))]
public struct Id : IComparable<Id>, IEquatable<Id>
{
// This implementation of Snowflake ID is based on the specification as published by Discord:
Expand Down
Loading