rabidus-test/Assets/Plugins/QFSW/Quantum Console/Source/Scripts/Serialization/QuantumSerializer.cs

106 lines
3.5 KiB
C#

using QFSW.QC.Utilities;
using System;
using System.Collections.Generic;
using System.Linq;
namespace QFSW.QC
{
/// <summary>
/// Handles formatted serialization for console returns.
/// </summary>
public class QuantumSerializer
{
private readonly IQcSerializer[] _serializers;
private readonly Dictionary<Type, IQcSerializer> _serializerLookup = new Dictionary<Type, IQcSerializer>();
private readonly HashSet<Type> _unserializableLookup = new HashSet<Type>();
private readonly Func<object, QuantumTheme, string> _recursiveSerializer;
/// <summary>
/// Creates a Quantum Serializer with a custom set of serializers.
/// </summary>
/// <param name="serializers">The IQcSerializers to use in this Quantum Serializer.</param>
public QuantumSerializer(IEnumerable<IQcSerializer> serializers)
{
_recursiveSerializer = SerializeFormatted;
_serializers = serializers.OrderByDescending(x => x.Priority)
.ToArray();
}
/// <summary>
/// Creates a Quantum Serializer with the default injected serializers
/// </summary>
public QuantumSerializer() : this(new InjectionLoader<IQcSerializer>().GetInjectedInstances())
{
}
/// <summary>
/// Serializes the object with formatting for displaying in the console.
/// </summary>
/// <param name="value">The value to format and serialize.</param>
/// <param name="theme">(Optional) QuantumTheme to use for formatting the results.</param>
/// <returns>The formatted serialization.</returns>
public string SerializeFormatted(object value, QuantumTheme theme = null)
{
if (value is null)
{
return string.Empty;
}
Type type = value.GetType();
string result = string.Empty;
string SerializeInternal(IQcSerializer serializer)
{
try
{
return serializer.SerializeFormatted(value, theme, _recursiveSerializer);
}
catch (Exception e)
{
throw new Exception($"Serialization of {type.GetDisplayName()} via {serializer} failed:\n{e.Message}", e);
}
}
if (_serializerLookup.ContainsKey(type))
{
result = SerializeInternal(_serializerLookup[type]);
}
else if (_unserializableLookup.Contains(type))
{
result = value.ToString();
}
else
{
bool converted = false;
foreach (IQcSerializer serializer in _serializers)
{
if (serializer.CanSerialize(type))
{
result = SerializeInternal(serializer);
_serializerLookup[type] = serializer;
converted = true;
break;
}
}
if (!converted)
{
result = value.ToString();
_unserializableLookup.Add(type);
}
}
if (theme && !string.IsNullOrWhiteSpace(result))
{
result = theme.ColorizeReturn(result, type);
}
return result;
}
}
}