Skip to content

Commit 21c25de

Browse files
committed
Add UUID built-in convenience type to SpacetimeDB
1 parent c7c0e66 commit 21c25de

77 files changed

Lines changed: 3873 additions & 74 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ unicode-ident = "1.0.12"
302302
unicode-normalization = "0.1.23"
303303
url = "2.3.1"
304304
urlencoding = "2.1.2"
305-
uuid = { version = "1.18.1", features = ["v4"] }
305+
uuid = { version = "1.18.1", default-features = false }
306306
v8 = "140.2"
307307
walkdir = "2.2.5"
308308
wasmbin = "0.6"

crates/bindings-csharp/BSATN.Runtime.Tests/Tests.cs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
namespace SpacetimeDB;
22

33
using System.Diagnostics.CodeAnalysis;
4+
using System.Security.Cryptography;
45
using CsCheck;
56
using SpacetimeDB.BSATN;
67
using Xunit;
@@ -861,4 +862,63 @@ public static void GeneratedEnumEqualsWorks()
861862
iter: 10_000
862863
);
863864
}
865+
866+
[Fact]
867+
public static void UUidRoundTrip()
868+
{
869+
var u1 = Uuid.NIL;
870+
var s = u1.ToString();
871+
var u2 = Uuid.Parse(s);
872+
Assert.Equal(u1, u2);
873+
Assert.Equal(u1.ToGuid(), u2.ToGuid());
874+
Assert.Equal(s, u2.ToString());
875+
}
876+
877+
[Fact]
878+
public static void UuidOrdered()
879+
{
880+
var u1 = new Uuid(new U128(1, 0));
881+
var u2 = new Uuid(new U128(2, 0));
882+
883+
Assert.True(u1 < u2);
884+
Assert.True(u2 > u1);
885+
Assert.Equal(u1, u1);
886+
Assert.NotEqual(u1, u2);
887+
888+
var clock = new ClockGenerator(new Timestamp());
889+
890+
var uuids = Enumerable
891+
.Range(0, 1000)
892+
.Select(_ =>
893+
{
894+
var bytes = new byte[10];
895+
RandomNumberGenerator.Fill(bytes);
896+
return Uuid.FromClockV7(clock, bytes);
897+
})
898+
.ToList();
899+
900+
for (var i = 0; i < uuids.Count - 1; i++)
901+
{
902+
var a = uuids[i];
903+
var b = uuids[i + 1];
904+
905+
Assert.True(a < b, $"UUIDs are not ordered at {i}: {a} !< {b}");
906+
}
907+
}
908+
909+
[Fact]
910+
public static void UuidVariant()
911+
{
912+
var u = Uuid.NIL;
913+
Assert.Equal(Uuid.UuidVariant.Nil, u.GetVariant());
914+
915+
var randomBytes = new byte[16];
916+
RandomNumberGenerator.Fill(randomBytes);
917+
u = Uuid.FromRandomBytesV4(randomBytes);
918+
Assert.Equal(Uuid.UuidVariant.V4, u.GetVariant());
919+
920+
var clock = new ClockGenerator(new Timestamp());
921+
u = Uuid.FromClockV7(clock, randomBytes.AsSpan()[..10]);
922+
Assert.Equal(Uuid.UuidVariant.V7, u.GetVariant()); // Version nibble
923+
}
864924
}

crates/bindings-csharp/BSATN.Runtime/BSATN/U128.cs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
namespace SpacetimeDB;
55

6+
using System.Buffers.Binary;
67
using System.Numerics;
78
using System.Runtime.InteropServices;
89

@@ -33,6 +34,33 @@ public U128(ulong upper, ulong lower)
3334

3435
internal ulong Upper => _upper;
3536

37+
/// Returns a <see cref="U128" /> from a big-endian byte array.
38+
public static U128 FromBytesBigEndian(ReadOnlySpan<byte> bytes)
39+
{
40+
if (bytes.Length != Size)
41+
{
42+
throw new ArgumentException(
43+
$"Byte array must be exactly {Size} bytes long.",
44+
nameof(bytes)
45+
);
46+
}
47+
48+
var upper = BinaryPrimitives.ReadUInt64BigEndian(bytes.Slice(0, 8));
49+
var lower = BinaryPrimitives.ReadUInt64BigEndian(bytes.Slice(8, 8));
50+
51+
return new U128(upper, lower);
52+
}
53+
54+
public byte[] ToBytesBigEndian()
55+
{
56+
var bytes = new byte[Size];
57+
58+
BinaryPrimitives.WriteUInt64BigEndian(bytes.AsSpan(0, 8), _upper);
59+
BinaryPrimitives.WriteUInt64BigEndian(bytes.AsSpan(8, 8), _lower);
60+
61+
return bytes;
62+
}
63+
3664
/// <inheritdoc cref="IComparable.CompareTo(object)" />
3765
public int CompareTo(object? value)
3866
{
@@ -90,4 +118,17 @@ private BigInteger AsBigInt() =>
90118

91119
/// <inheritdoc cref="object.ToString()" />
92120
public override string ToString() => AsBigInt().ToString();
121+
122+
public Guid ToGuid()
123+
{
124+
var bytes = ToBytesBigEndian();
125+
return new Guid(bytes);
126+
}
127+
128+
public static U128 FromGuid(Guid guid)
129+
{
130+
Span<byte> bytes = stackalloc byte[16];
131+
guid.TryWriteBytes(bytes);
132+
return FromBytesBigEndian(bytes);
133+
}
93134
}

0 commit comments

Comments
 (0)