141 lines
4.7 KiB
C#
141 lines
4.7 KiB
C#
using System;
|
|
using System.Reflection;
|
|
|
|
namespace AyCode.Core.Serializers;
|
|
|
|
public abstract class AcSerializerOptions
|
|
{
|
|
public int MaxContextPoolSize { get; init; } = 8;
|
|
public abstract AcSerializerType SerializerType { get; init; }
|
|
|
|
/// <summary>
|
|
/// Reference handling mode for circular/shared references.
|
|
/// Default: OnlyId (JSON serializer requires All mode, OnlyId not yet implemented)
|
|
/// Note: Binary serializer supports OnlyId mode for IId-only tracking.
|
|
/// </summary>
|
|
public ReferenceHandlingMode ReferenceHandling
|
|
{
|
|
get => _referenceHandling;
|
|
set => _referenceHandling = value;
|
|
}
|
|
|
|
private ReferenceHandlingMode _referenceHandling = ReferenceHandlingMode.OnlyId;
|
|
|
|
private readonly byte _maxDepth = byte.MaxValue;
|
|
private readonly bool _throwOnCircularReference = true;
|
|
private readonly PropertyMapperDelegate? _propertyMapper;
|
|
|
|
private bool _useAsync = false;
|
|
|
|
public bool UseAsync
|
|
{
|
|
get => _useAsync && (ReferenceHandling != ReferenceHandlingMode.None); //|| UseStringIntern)
|
|
init => _useAsync = !DetectedIsWasm && value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Cached platform detection - true if running in WebAssembly/Browser environment.
|
|
/// </summary>
|
|
protected static readonly bool DetectedIsWasm = OperatingSystem.IsBrowser();
|
|
|
|
/// <summary>
|
|
/// Maximum depth for serialization/deserialization.
|
|
/// 0 = root level only (primitives of root object)
|
|
/// 1 = root + first level of nested objects/collections
|
|
/// byte.MaxValue (255) = effectively unlimited
|
|
/// Default: byte.MaxValue
|
|
/// </summary>
|
|
public byte MaxDepth
|
|
{
|
|
get => _maxDepth;
|
|
init => _maxDepth = value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Throw exception on circular reference detection for non-IId types.
|
|
/// When true: Tracks all objects and throws InvalidOperationException on circular references.
|
|
/// When false: No tracking for non-IId types (faster, but circular refs may cause MaxDepth truncation).
|
|
/// Default: true (production safety)
|
|
/// Note: IId types are always tracked when ReferenceHandling != None.
|
|
/// </summary>
|
|
public bool ThrowOnCircularReference
|
|
{
|
|
get => _throwOnCircularReference;
|
|
init => _throwOnCircularReference = value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Optional callback for custom property mapping during cross-type operations.
|
|
/// Used when deserializing/populating with Deserialize<TSource, TDest> or Populate<TSource, TDest>.
|
|
///
|
|
/// Use cases:
|
|
/// - Mapping between external DTOs and internal models (different class hierarchies)
|
|
/// - Handling property renames across versions
|
|
/// - Custom property pairing logic
|
|
///
|
|
/// If null (default), properties are matched by name.
|
|
/// Callback is invoked once during mapping build phase and result is cached.
|
|
///
|
|
/// Performance: ZERO overhead on same-type operations (Deserialize<T>).
|
|
/// </summary>
|
|
public PropertyMapperDelegate? PropertyMapper
|
|
{
|
|
get => _propertyMapper;
|
|
init => _propertyMapper = value;
|
|
}
|
|
}
|
|
|
|
public enum AcSerializerType : byte
|
|
{
|
|
Json = 0,
|
|
Binary = 1,
|
|
Toon = 2,
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reference handling mode for serialization.
|
|
/// </summary>
|
|
public enum ReferenceHandlingMode : byte
|
|
{
|
|
/// <summary>
|
|
/// No reference handling - all objects serialized inline.
|
|
/// </summary>
|
|
None = 0,
|
|
|
|
/// <summary>
|
|
/// Reference handling only for IId objects - uses semantic Id for deduplication.
|
|
/// NOTE: Not fully implemented for JSON serializer - use All instead.
|
|
/// Binary serializer supports this mode.
|
|
/// </summary>
|
|
OnlyId = 1,
|
|
|
|
/// <summary>
|
|
/// Full reference handling for all objects.
|
|
/// </summary>
|
|
All = 2
|
|
}
|
|
|
|
/// <summary>
|
|
/// Wire encoding mode for binary serialization.
|
|
/// </summary>
|
|
public enum WireMode : byte
|
|
{
|
|
/// <summary>
|
|
/// Compact encoding: VarInt for integers, UTF-8 for strings. Smaller output.
|
|
/// </summary>
|
|
Compact = 0,
|
|
|
|
/// <summary>
|
|
/// Fast encoding: fixed-width integers, UTF-16 for strings. Larger output, faster encode/decode.
|
|
/// </summary>
|
|
Fast = 1
|
|
}
|
|
|
|
/// <summary>
|
|
/// Delegate for custom property mapping during cross-type deserialization/population.
|
|
/// Enables mapping between different class hierarchies or renamed properties.
|
|
/// </summary>
|
|
/// <param name="sourceProperty">Property from the source type being deserialized</param>
|
|
/// <param name="destinationType">Target type being populated</param>
|
|
/// <returns>Mapped destination property, or null to skip this property</returns>
|
|
public delegate PropertyInfo? PropertyMapperDelegate(PropertyInfo sourceProperty, Type destinationType); |