using Lattice.Core.Docking.Abstractions;
using Lattice.Core.Docking.Engine;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Lattice.Serialization.Docking;
///
/// Реализация сериализатора макета док-системы в формате JSON с использованием System.Text.Json.
/// Предоставляет высокопроизводительную сериализацию и десериализацию с поддержкой
/// опций кастомизации через .
///
///
/// Этот сериализатор использует преобразователь для
/// трансформации между объектной моделью и DTO, что обеспечивает независимость
/// формата JSON от внутренней структуры данных.
///
public class JsonLayoutSerializer : ILayoutSerializer
{
private readonly JsonSerializerOptions _options;
///
/// Инициализирует новый экземпляр JSON-сериализатора с настройками по умолчанию.
///
public JsonLayoutSerializer() : this(null)
{
}
///
/// Инициализирует новый экземпляр JSON-сериализатора с указанными опциями.
///
///
/// Опции сериализации JSON. Если не указаны, используются стандартные опции.
///
public JsonLayoutSerializer(JsonSerializerOptions? options)
{
_options = options ?? CreateDefaultOptions();
}
///
public string FormatId => "json";
///
public string MimeType => "application/json";
///
public string DefaultFileExtension => ".json";
///
public byte[] Serialize(LayoutManager manager)
{
if (manager == null)
throw new ArgumentNullException(nameof(manager));
var dto = LayoutConverter.ConvertToDto(manager);
return JsonSerializer.SerializeToUtf8Bytes(dto, _options);
}
///
public string SerializeToString(LayoutManager manager)
{
if (manager == null)
throw new ArgumentNullException(nameof(manager));
var dto = LayoutConverter.ConvertToDto(manager);
return JsonSerializer.Serialize(dto, _options);
}
///
public void SerializeToStream(LayoutManager manager, Stream stream)
{
if (manager == null)
throw new ArgumentNullException(nameof(manager));
if (stream == null)
throw new ArgumentNullException(nameof(stream));
var dto = LayoutConverter.ConvertToDto(manager);
JsonSerializer.Serialize(stream, dto, _options);
}
///
public void Deserialize(LayoutManager manager, byte[] data, Func contentResolver)
{
if (manager == null)
throw new ArgumentNullException(nameof(manager));
if (data == null)
throw new ArgumentNullException(nameof(data));
var dto = JsonSerializer.Deserialize(data, _options);
if (dto == null)
throw new InvalidOperationException("Failed to deserialize layout data");
LayoutConverter.RestoreFromDto(manager, dto, contentResolver);
}
///
public void DeserializeFromString(LayoutManager manager, string serializedData,
Func contentResolver)
{
if (manager == null)
throw new ArgumentNullException(nameof(manager));
if (serializedData == null)
throw new ArgumentNullException(nameof(serializedData));
var dto = JsonSerializer.Deserialize(serializedData, _options);
if (dto == null)
throw new InvalidOperationException("Failed to deserialize layout string");
LayoutConverter.RestoreFromDto(manager, dto, contentResolver);
}
///
public void DeserializeFromStream(LayoutManager manager, Stream stream,
Func contentResolver)
{
if (manager == null)
throw new ArgumentNullException(nameof(manager));
if (stream == null)
throw new ArgumentNullException(nameof(stream));
var dto = JsonSerializer.Deserialize(stream, _options);
if (dto == null)
throw new InvalidOperationException("Failed to deserialize layout stream");
LayoutConverter.RestoreFromDto(manager, dto, contentResolver);
}
///
/// Создает стандартные опции сериализации JSON.
///
/// Экземпляр с настройками по умолчанию.
private static JsonSerializerOptions CreateDefaultOptions()
{
return new JsonSerializerOptions
{
WriteIndented = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
Converters = { new JsonStringEnumConverter() },
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
ReferenceHandler = ReferenceHandler.IgnoreCycles,
PropertyNameCaseInsensitive = true,
AllowTrailingCommas = true,
ReadCommentHandling = JsonCommentHandling.Skip,
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};
}
}