This commit is contained in:
Даниил Заикин
2026-06-17 20:44:53 +03:00
parent 9d153773c2
commit b133e7c656
1880 changed files with 244545 additions and 0 deletions
@@ -0,0 +1,33 @@
using System;
namespace QFSW.QC
{
/// <summary>
/// Serializer for a single type.
/// </summary>
/// <typeparam name="T">The type to serialize.</typeparam>
public abstract class BasicQcSerializer<T> : IQcSerializer
{
private Func<object, QuantumTheme, string> _recursiveSerializer;
public virtual int Priority => 0;
public bool CanSerialize(Type type)
{
return type == typeof(T);
}
string IQcSerializer.SerializeFormatted(object value, QuantumTheme theme, Func<object, QuantumTheme, string> recursiveSerializer)
{
_recursiveSerializer = recursiveSerializer;
return SerializeFormatted((T)value, theme);
}
protected string SerializeRecursive(object value, QuantumTheme theme)
{
return _recursiveSerializer(value, theme);
}
public abstract string SerializeFormatted(T value, QuantumTheme theme);
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8ca902898efebc44eb68a9de6f50a37b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,51 @@
using QFSW.QC.Utilities;
using System;
namespace QFSW.QC
{
/// <summary>
/// Serializer for all types that are generic constructions of a single type.
/// </summary>
public abstract class GenericQcSerializer : IQcSerializer
{
/// <summary>
/// The incomplete generic type of this serializer.
/// </summary>
protected abstract Type GenericType { get; }
private Func<object, QuantumTheme, string> _recursiveSerializer;
protected GenericQcSerializer()
{
if (!GenericType.IsGenericType)
{
throw new ArgumentException($"Generic Serializers must use a generic type as their base");
}
if (GenericType.IsConstructedGenericType)
{
throw new ArgumentException($"Generic Serializers must use an incomplete generic type as their base");
}
}
public virtual int Priority => -500;
public bool CanSerialize(Type type)
{
return type.IsGenericTypeOf(GenericType);
}
string IQcSerializer.SerializeFormatted(object value, QuantumTheme theme, Func<object, QuantumTheme, string> recursiveSerializer)
{
_recursiveSerializer = recursiveSerializer;
return SerializeFormatted(value, theme);
}
protected string SerializeRecursive(object value, QuantumTheme theme)
{
return _recursiveSerializer(value, theme);
}
public abstract string SerializeFormatted(object value, QuantumTheme theme);
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a7640a2497d7d04489df10e2a4d1c7ad
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,31 @@
using System;
namespace QFSW.QC
{
/// <summary>
/// Creates a Serializer that is loaded and used by the QuantumSerializer.
/// </summary>
public interface IQcSerializer
{
/// <summary>
/// The priority of this serializer to resolve multiple serializers covering the same type.
/// </summary>
int Priority { get; }
/// <summary>
/// If this serializer can serialize the incoming type.
/// </summary>
/// <param name="type">The type to test.</param>
/// <returns>If it can serialize.</returns>
bool CanSerialize(Type type);
/// <summary>
/// Serializes the incoming data.
/// </summary>
/// <param name="value">The value to serialize.</param>
/// <param name="theme">The (optional) theme to use for formatted serialization.</param>
/// <param name="recursiveSerializer">Delegate back to the main serializer to allow for recursive serialization of sub elements.</param>
/// <returns>The serialized result.</returns>
string SerializeFormatted(object value, QuantumTheme theme, Func<object, QuantumTheme, string> recursiveSerializer);
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 34cdc555ca8a54e44863b4552852df71
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,33 @@
using System;
namespace QFSW.QC
{
/// <summary>
/// Serializer for all types inheriting from a single type.
/// </summary>
/// <typeparam name="T">Base type of the types to serialize.</typeparam>
public abstract class PolymorphicQcSerializer<T> : IQcSerializer where T : class
{
private Func<object, QuantumTheme, string> _recursiveSerializer;
public virtual int Priority => -1000;
public bool CanSerialize(Type type)
{
return typeof(T).IsAssignableFrom(type);
}
string IQcSerializer.SerializeFormatted(object value, QuantumTheme theme, Func<object, QuantumTheme, string> recursiveSerializer)
{
_recursiveSerializer = recursiveSerializer;
return SerializeFormatted((T)value, theme);
}
protected string SerializeRecursive(object value, QuantumTheme theme)
{
return _recursiveSerializer(value, theme);
}
public abstract string SerializeFormatted(T value, QuantumTheme theme);
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fca63e83ffbf0884fb2f5910dc3ecec4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,105 @@
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;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ee15beb7bc84a94449abebd99629b1bb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3ea795e317dd5b64f8b699ef7a640f92
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,15 @@
using System.Collections;
namespace QFSW.QC.Serializers
{
public class DictionaryEntrySerializer : BasicQcSerializer<DictionaryEntry>
{
public override string SerializeFormatted(DictionaryEntry value, QuantumTheme theme)
{
string innerKey = SerializeRecursive(value.Key, theme);
string innerValue = SerializeRecursive(value.Value, theme);
return $"{innerKey}: {innerValue}";
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8f5ea7a0667903a4a81ff2b0253cf886
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,15 @@
using System.Collections;
namespace QFSW.QC.Serializers
{
public class IDictionarySerializer : IEnumerableSerializer<IDictionary>
{
protected override IEnumerable GetObjectStream(IDictionary value)
{
foreach (DictionaryEntry item in value)
{
yield return item;
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ecd3d9e7bdfeaa1478f9a208e8251397
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,59 @@
using QFSW.QC.Pooling;
using System;
using System.Collections;
using System.Text;
namespace QFSW.QC.Serializers
{
public class IEnumerableSerializer : IEnumerableSerializer<IEnumerable>
{
public override int Priority => base.Priority - 1000;
protected override IEnumerable GetObjectStream(IEnumerable value)
{
return value;
}
}
public abstract class IEnumerableSerializer<T> : PolymorphicQcSerializer<T> where T : class, IEnumerable
{
private readonly StringBuilderPool _builderPool = new StringBuilderPool();
public override string SerializeFormatted(T value, QuantumTheme theme)
{
Type type = value.GetType();
StringBuilder builder = _builderPool.GetStringBuilder();
string left = "[";
string seperator = ",";
string right = "]";
if (theme)
{
theme.GetCollectionFormatting(type, out left, out seperator, out right);
}
builder.Append(left);
bool firstIteration = true;
foreach (object item in GetObjectStream(value))
{
if (firstIteration)
{
firstIteration = false;
}
else
{
builder.Append(seperator);
}
builder.Append(SerializeRecursive(item, theme));
}
builder.Append(right);
return _builderPool.ReleaseAndToString(builder);
}
protected abstract IEnumerable GetObjectStream(T value);
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 85d1c77e99db74c4786c67db88eed3ce
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,21 @@
#if !NET_STANDARD_2_0
using System.Runtime.CompilerServices;
namespace QFSW.QC.Serializers
{
public class ITupleSerializer : PolymorphicQcSerializer<ITuple>
{
public override string SerializeFormatted(ITuple value, QuantumTheme theme)
{
string[] serializedItems = new string[value.Length];
for (int i = 0; i < value.Length; i++)
{
serializedItems[i] = SerializeRecursive(value[i], theme);
}
return $"({string.Join(", ", serializedItems)})";
}
}
}
#endif
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a98f9dc2d30e50a4ea3e6b10d5af4d1a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Reflection;
namespace QFSW.QC.Serializers
{
public class KeyValuePairSerializer : GenericQcSerializer
{
protected override Type GenericType { get; } = typeof(KeyValuePair<,>);
private readonly Dictionary<Type, PropertyInfo> _keyPropertyLookup = new Dictionary<Type, PropertyInfo>();
private readonly Dictionary<Type, PropertyInfo> _valuePropertyLookup = new Dictionary<Type, PropertyInfo>();
public override string SerializeFormatted(object value, QuantumTheme theme)
{
Type type = value.GetType();
PropertyInfo keyProperty;
PropertyInfo valueProperty;
if (_keyPropertyLookup.ContainsKey(type))
{
keyProperty = _keyPropertyLookup[type];
}
else
{
keyProperty = type.GetProperty("Key");
_keyPropertyLookup[type] = keyProperty;
}
if (_valuePropertyLookup.ContainsKey(type))
{
valueProperty = _valuePropertyLookup[type];
}
else
{
valueProperty = type.GetProperty("Value");
_valuePropertyLookup[type] = valueProperty;
}
string innerKey = SerializeRecursive(keyProperty.GetValue(value, null), theme);
string innerValue = SerializeRecursive(valueProperty.GetValue(value, null), theme);
return $"{innerKey}: {innerValue}";
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 90dd2bea123ca7a43b2aee4e0985bd0f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,14 @@
{
"name": "QFSW.QC.Serializers",
"references": [
"QFSW.QC"
],
"optionalUnityReferences": [],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": []
}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: b2b4ba6eb36b7bb49beadaf8e4db329a
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,12 @@
namespace QFSW.QC.Serializers
{
public class StringSerializer : BasicQcSerializer<string>
{
public override int Priority => int.MaxValue;
public override string SerializeFormatted(string value, QuantumTheme theme)
{
return value;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a7a677dc32186804cb64e985537c4e21
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,13 @@
using QFSW.QC.Utilities;
using System;
namespace QFSW.QC.Serializers
{
public class TypeSerialiazer : PolymorphicQcSerializer<Type>
{
public override string SerializeFormatted(Type value, QuantumTheme theme)
{
return value.GetDisplayName();
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a0081da50a0ad3743b7adaa7f49a327d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,12 @@
using UnityEngine;
namespace QFSW.QC.Serializers
{
public class UnityObjectSerializer : PolymorphicQcSerializer<Object>
{
public override string SerializeFormatted(Object value, QuantumTheme theme)
{
return value.name;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 85179674c3db5514082e498f38a169d6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,12 @@
using UnityEngine;
namespace QFSW.QC.Serializers
{
public class Vector2IntSerializer : BasicQcSerializer<Vector2Int>
{
public override string SerializeFormatted(Vector2Int value, QuantumTheme theme)
{
return $"({value.x}, {value.y})";
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c966e27c828cfa84b80e8bf5c057176b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,12 @@
using UnityEngine;
namespace QFSW.QC.Serializers
{
public class Vector2Serializer : BasicQcSerializer<Vector2>
{
public override string SerializeFormatted(Vector2 value, QuantumTheme theme)
{
return $"({value.x}, {value.y})";
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 84fbe7c52769e5049af7ac1c1ccf0c1a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,12 @@
using UnityEngine;
namespace QFSW.QC.Serializers
{
public class Vector3IntSerializer : BasicQcSerializer<Vector3Int>
{
public override string SerializeFormatted(Vector3Int value, QuantumTheme theme)
{
return $"({value.x}, {value.y}, {value.z})";
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e04a3eb24be1a7f4f80c1c53290fed34
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,12 @@
using UnityEngine;
namespace QFSW.QC.Serializers
{
public class Vector3Serializer : BasicQcSerializer<Vector3>
{
public override string SerializeFormatted(Vector3 value, QuantumTheme theme)
{
return $"({value.x}, {value.y}, {value.z})";
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d55001e28a383304ab174d2aed504aa6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,12 @@
using UnityEngine;
namespace QFSW.QC.Serializers
{
public class Vector4Serializer : BasicQcSerializer<Vector4>
{
public override string SerializeFormatted(Vector4 value, QuantumTheme theme)
{
return $"({value.x}, {value.y}, {value.z}, {value.w})";
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: af0a28dfe0d28b844b9ca788f93145c2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: