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 }; } }