Skip to content

Commit

Permalink
Fix several serialization bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
halgari committed Jan 10, 2024
1 parent c223169 commit a48dff3
Show file tree
Hide file tree
Showing 14 changed files with 64 additions and 108 deletions.
20 changes: 18 additions & 2 deletions src/NexusMods.EventSourcing.Abstractions/EntityId.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public static EntityId NewId()
var value = BinaryPrimitives.ReadUInt128BigEndian(bytes);
return From(value);
}

public static EntityId From(ReadOnlySpan<byte> data) => new(BinaryPrimitives.ReadUInt128BigEndian(data));

public void TryWriteBytes(Span<byte> span)
Expand Down Expand Up @@ -48,14 +48,30 @@ public void TryWriteBytes(Span<byte> span)
/// <returns></returns>
public static EntityId<T> From(UInt128 id) => new(EntityId.From(id));

/// <summary>
/// Reads the <see cref="EntityId{T}"/> from the specified <paramref name="data"/>.
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static EntityId<T> From(ReadOnlySpan<byte> data) => new(EntityId.From(data));



/// <summary>
/// Gets the <see cref="EntityId{T}"/> from the specified <paramref name="id"/>.
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public static EntityId<T> From(string id) => From(UInt128.Parse(id, NumberStyles.HexNumber));
public static EntityId<T> From(string id)
{
if (Guid.TryParse(id, out var guid))
{
Span<byte> bytes = stackalloc byte[16];
guid.TryWriteBytes(bytes);
return From(BinaryPrimitives.ReadUInt128BigEndian(bytes));
}
return From(UInt128.Parse(id, NumberStyles.HexNumber));
}


/// <summary>
Expand Down
50 changes: 0 additions & 50 deletions src/NexusMods.EventSourcing/EventFormatter.cs

This file was deleted.

38 changes: 0 additions & 38 deletions src/NexusMods.EventSourcing/EventSerializer.cs

This file was deleted.

6 changes: 4 additions & 2 deletions src/NexusMods.EventSourcing/Serialization/ArraySerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,13 @@ public void Serialize<TWriter>(TItem[] value, TWriter output) where TWriter : IB
{
var totalSize = sizeof(ushort) + (itemSize * value.Length);
var span = output.GetSpan(totalSize);
BinaryPrimitives.WriteUInt32BigEndian(span, (ushort)value.Length);
BinaryPrimitives.WriteUInt16BigEndian(span, (ushort)value.Length);

var offset = sizeof(ushort);
foreach (var item in value)
{
itemSerializer.Serialize(item, span.SliceFast(itemSize, itemSize));
itemSerializer.Serialize(item, span.SliceFast(offset, itemSize));
offset += itemSize;
}
output.Advance(totalSize);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,6 @@ public void Serialize(EntityId<T> value, Span<byte> output)

public EntityId<T> Deserialize(ReadOnlySpan<byte> from)
{
return EntityId<T>.From(BinaryPrimitives.ReadUInt64BigEndian(from));
return EntityId<T>.From(from);
}
}
5 changes: 3 additions & 2 deletions src/NexusMods.EventSourcing/Serialization/StringSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Buffers;
using System.Buffers.Binary;
using NexusMods.EventSourcing.Abstractions.Serialization;
using Reloaded.Memory.Extensions;

namespace NexusMods.EventSourcing.Serialization;

Expand All @@ -23,14 +24,14 @@ public void Serialize<TWriter>(string value, TWriter output) where TWriter : IBu
var size = System.Text.Encoding.UTF8.GetByteCount(value);
var span = output.GetSpan(size + 2);
BinaryPrimitives.WriteUInt16LittleEndian(span, (ushort)size);
System.Text.Encoding.UTF8.GetBytes(value, span[2..]);
System.Text.Encoding.UTF8.GetBytes(value, span.SliceFast(2));
output.Advance(size + 2);
}

public int Deserialize(ReadOnlySpan<byte> from, out string value)
{
var size = BinaryPrimitives.ReadUInt16LittleEndian(from);
value = System.Text.Encoding.UTF8.GetString(from[2..(2 + size)]);
value = System.Text.Encoding.UTF8.GetString(from.SliceFast(2, size));
return size + 2;
}
}
2 changes: 1 addition & 1 deletion src/NexusMods.EventSourcing/Services.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public static IServiceCollection AddEventSourcing(this IServiceCollection servic
.AddSingleton<ISerializer, GenericEntityIdSerializer>()
.AddSingleton<ISerializer, StringSerializer>()
.AddSingleton<ISerializer, BoolSerializer>()
.AddSingleton<EventSerializer>()
.AddSingleton<BinaryEventSerializer>()
.AddSingleton<ISerializer, UInt8Serializer>()
.AddSingleton<ISerializer, UInt32Serializer>()
.AddSingleton<ISerializer, EntityIdSerializer>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
namespace NexusMods.EventSourcing.TestModel.Events;

[EventId("9C6CF87E-9469-4C9E-87AB-6FE7EF331358")]
[MemoryPackable]
public partial record AddCollection(EntityId<Collection> CollectionId, string Name, EntityId<Loadout> LoadoutId, EntityId<Mod>[] Mods) : IEvent
public record AddCollection(EntityId<Collection> CollectionId, string Name, EntityId<Loadout> LoadoutId, EntityId<Mod>[] Mods) : IEvent
{
public void Apply<T>(T context) where T : IEventContext
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Specialized;
using NexusMods.EventSourcing.Abstractions;
using NexusMods.EventSourcing.Serialization;
using NexusMods.EventSourcing.TestModel;
using NexusMods.EventSourcing.TestModel.Events;
using NexusMods.EventSourcing.TestModel.Model;
Expand All @@ -9,9 +10,9 @@ namespace NexusMods.EventSourcing.Tests;
public class BasicFunctionalityTests
{
private readonly IEntityContext _ctx;
public BasicFunctionalityTests(EventSerializer serializer)
public BasicFunctionalityTests(BinaryEventSerializer serializer)
{
var store = new InMemoryEventStore<EventSerializer>(serializer);
var store = new InMemoryEventStore<BinaryEventSerializer>(serializer);
_ctx = new EntityContext(store);
}

Expand Down Expand Up @@ -57,7 +58,7 @@ public void CanLinkEntities()
tx.Commit();

var loadout = _ctx.Get(loadoutId);
loadout.Mods.Count().Should().Be(1);
loadout.Mods.Count.Should().Be(1);
loadout.Mods.First().Name.Should().Be("First Mod");

var mod = _ctx.Get(modId);
Expand Down
3 changes: 2 additions & 1 deletion tests/NexusMods.EventSourcing.Tests/EventSerializerTests.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
using NexusMods.EventSourcing.Abstractions;
using NexusMods.EventSourcing.Serialization;
using NexusMods.EventSourcing.TestModel.Events;
using NexusMods.EventSourcing.TestModel.Model;

namespace NexusMods.EventSourcing.Tests;

public class EventSerializerTests(EventSerializer serializer)
public class EventSerializerTests(BinaryEventSerializer serializer)
{

[Fact]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
using NexusMods.EventSourcing.Serialization;
using NexusMods.EventSourcing.TestModel;

namespace NexusMods.EventSourcing.Tests.EventStoreTests;

public class InMemoryEventStoreTests : AEventStoreTest<InMemoryEventStore<EventSerializer>>
public class InMemoryEventStoreTests : AEventStoreTest<InMemoryEventStore<BinaryEventSerializer>>
{
public InMemoryEventStoreTests(EventSerializer serializer) : base(new InMemoryEventStore<EventSerializer>(serializer)) { }
public InMemoryEventStoreTests(BinaryEventSerializer serializer) : base(new InMemoryEventStore<BinaryEventSerializer>(serializer)) { }
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
using NexusMods.EventSourcing.RocksDB;
using NexusMods.EventSourcing.Serialization;
using NexusMods.Paths;

namespace NexusMods.EventSourcing.Tests.EventStoreTests;

public class RocksDBEventStoreTests(EventSerializer serializer) : AEventStoreTest<RocksDBEventStore<EventSerializer>>(
new RocksDBEventStore<EventSerializer>(serializer, new Settings
public class RocksDBEventStoreTests(BinaryEventSerializer serializer) : AEventStoreTest<RocksDBEventStore<BinaryEventSerializer>>(
new RocksDBEventStore<BinaryEventSerializer>(serializer, new Settings
{
StorageLocation = FileSystem.Shared.GetKnownPath(KnownPath.EntryDirectory)
.Combine("FasterKV.EventStore" + Guid.NewGuid())
Expand Down
23 changes: 23 additions & 0 deletions tests/NexusMods.EventSourcing.Tests/SerializationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,30 @@ public void CanSerializeEvents()

var deserialized = serializer.Deserialize(serialized);
deserialized.Should().Be(evnt);
}

[Theory]
[MemberData(nameof(ExampleEvents))]
public void CanSerializeAllEvents(IEvent @event)
{
var serialized = serializer.Serialize(@event);
var deserialized = serializer.Deserialize(serialized);
deserialized.Should()
.BeEquivalentTo(@event, opts => opts.RespectingRuntimeTypes());
}

public static IEnumerable<object[]> ExampleEvents()
{
var events = new List<object[]>
{
new object[]{new CreateLoadout(EntityId<Loadout>.NewId(), "Test")},
new object[]{new RenameLoadout(EntityId<Loadout>.NewId(), "Test")},
new object[]{new AddMod("New Mod", true, EntityId<Mod>.NewId(), new EntityId<Loadout>())},
new object[]{new AddCollection(EntityId<Collection>.NewId(), "NewCollection", EntityId<Loadout>.NewId(),
[EntityId<Mod>.NewId()])
},
};
return events;
}


Expand Down
3 changes: 1 addition & 2 deletions tests/NexusMods.EventSourcing.Tests/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ public class Startup
public void ConfigureServices(IServiceCollection container)
{
container
.AddSingleton<BinaryEventSerializer>()
.AddSingleton<IEventStore, InMemoryEventStore<EventSerializer>>()
.AddSingleton<IEventStore, InMemoryEventStore<BinaryEventSerializer>>()
.AddEvents()
.AddEvent<SimpleTestEvent>()
.AddEventSourcing()
Expand Down

0 comments on commit a48dff3

Please sign in to comment.