95 lines
3.3 KiB
C#
95 lines
3.3 KiB
C#
using System.Collections;
|
|
using System.Runtime.CompilerServices;
|
|
using AyCode.Core.Helpers;
|
|
using static AyCode.Core.Helpers.JsonUtilities;
|
|
|
|
namespace AyCode.Core.Serializers;
|
|
|
|
/// <summary>
|
|
/// Helper class for merging IId collections during deserialization.
|
|
/// Shared between JSON and Binary deserializers.
|
|
/// </summary>
|
|
public static class IIdCollectionMergeHelper
|
|
{
|
|
/// <summary>
|
|
/// Builds a lookup dictionary from an existing IId collection.
|
|
/// Maps Id values to their corresponding items.
|
|
/// </summary>
|
|
/// <param name="existingList">The existing collection to index.</param>
|
|
/// <param name="idGetter">Function to extract Id from an item.</param>
|
|
/// <param name="idType">The type of the Id property.</param>
|
|
/// <returns>Dictionary mapping Id to item, or null if collection is empty.</returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Dictionary<object, object>? BuildIdLookup(
|
|
IList existingList,
|
|
Func<object, object?> idGetter,
|
|
Type idType)
|
|
{
|
|
var count = existingList.Count;
|
|
if (count == 0) return null;
|
|
|
|
var dict = new Dictionary<object, object>(count);
|
|
for (var i = 0; i < count; i++)
|
|
{
|
|
var item = existingList[i];
|
|
if (item == null) continue;
|
|
|
|
var id = idGetter(item);
|
|
if (id != null && !IsDefaultValue(id, idType))
|
|
dict[id] = item;
|
|
}
|
|
return dict;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Removes orphaned items from the collection that are not present in the source IDs.
|
|
/// </summary>
|
|
/// <param name="existingList">The collection to clean up.</param>
|
|
/// <param name="existingById">Lookup dictionary of existing items.</param>
|
|
/// <param name="sourceIds">Set of IDs that were seen in source data.</param>
|
|
public static void RemoveOrphanedItems(
|
|
IList existingList,
|
|
Dictionary<object, object> existingById,
|
|
HashSet<object> sourceIds)
|
|
{
|
|
var itemsToRemove = new List<object>();
|
|
foreach (var kvp in existingById)
|
|
{
|
|
if (!sourceIds.Contains(kvp.Key))
|
|
{
|
|
itemsToRemove.Add(kvp.Value);
|
|
}
|
|
}
|
|
|
|
foreach (var item in itemsToRemove)
|
|
{
|
|
existingList.Remove(item);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Copies properties from source object to target object using metadata.
|
|
/// </summary>
|
|
/// <typeparam name="TPropertyInfo">Type of property info (varies by serializer).</typeparam>
|
|
/// <param name="source">Source object to copy from.</param>
|
|
/// <param name="target">Target object to copy to.</param>
|
|
/// <param name="properties">Array of property accessors.</param>
|
|
/// <param name="getter">Function to get property value.</param>
|
|
/// <param name="setter">Action to set property value.</param>
|
|
public static void CopyProperties<TPropertyInfo>(
|
|
object source,
|
|
object target,
|
|
TPropertyInfo[] properties,
|
|
Func<TPropertyInfo, object, object?> getter,
|
|
Action<TPropertyInfo, object, object?> setter)
|
|
{
|
|
for (var i = 0; i < properties.Length; i++)
|
|
{
|
|
var prop = properties[i];
|
|
var value = getter(prop, source);
|
|
if (value != null)
|
|
setter(prop, target, value);
|
|
}
|
|
}
|
|
}
|