Files
Lattice/Lattice.Serialization.Docking.Json/JsonLayoutSerializer.cs
2026-01-18 16:33:35 +03:00

147 lines
5.7 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Lattice.Core.Docking.Abstractions;
using Lattice.Core.Docking.Engine;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Lattice.Serialization.Docking;
/// <summary>
/// Реализация сериализатора макета док-системы в формате JSON с использованием System.Text.Json.
/// Предоставляет высокопроизводительную сериализацию и десериализацию с поддержкой
/// опций кастомизации через <see cref="JsonSerializerOptions"/>.
/// </summary>
/// <remarks>
/// Этот сериализатор использует преобразователь <see cref="LayoutConverter"/> для
/// трансформации между объектной моделью и DTO, что обеспечивает независимость
/// формата JSON от внутренней структуры данных.
/// </remarks>
public class JsonLayoutSerializer : ILayoutSerializer
{
private readonly JsonSerializerOptions _options;
/// <summary>
/// Инициализирует новый экземпляр JSON-сериализатора с настройками по умолчанию.
/// </summary>
public JsonLayoutSerializer() : this(null)
{
}
/// <summary>
/// Инициализирует новый экземпляр JSON-сериализатора с указанными опциями.
/// </summary>
/// <param name="options">
/// Опции сериализации JSON. Если не указаны, используются стандартные опции.
/// </param>
public JsonLayoutSerializer(JsonSerializerOptions? options)
{
_options = options ?? CreateDefaultOptions();
}
/// <inheritdoc/>
public string FormatId => "json";
/// <inheritdoc/>
public string MimeType => "application/json";
/// <inheritdoc/>
public string DefaultFileExtension => ".json";
/// <inheritdoc/>
public byte[] Serialize(LayoutManager manager)
{
if (manager == null)
throw new ArgumentNullException(nameof(manager));
var dto = LayoutConverter.ConvertToDto(manager);
return JsonSerializer.SerializeToUtf8Bytes(dto, _options);
}
/// <inheritdoc/>
public string SerializeToString(LayoutManager manager)
{
if (manager == null)
throw new ArgumentNullException(nameof(manager));
var dto = LayoutConverter.ConvertToDto(manager);
return JsonSerializer.Serialize(dto, _options);
}
/// <inheritdoc/>
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);
}
/// <inheritdoc/>
public void Deserialize(LayoutManager manager, byte[] data, Func<string, IDockContent?> contentResolver)
{
if (manager == null)
throw new ArgumentNullException(nameof(manager));
if (data == null)
throw new ArgumentNullException(nameof(data));
var dto = JsonSerializer.Deserialize<LayoutDto>(data, _options);
if (dto == null)
throw new InvalidOperationException("Failed to deserialize layout data");
LayoutConverter.RestoreFromDto(manager, dto, contentResolver);
}
/// <inheritdoc/>
public void DeserializeFromString(LayoutManager manager, string serializedData,
Func<string, IDockContent?> contentResolver)
{
if (manager == null)
throw new ArgumentNullException(nameof(manager));
if (serializedData == null)
throw new ArgumentNullException(nameof(serializedData));
var dto = JsonSerializer.Deserialize<LayoutDto>(serializedData, _options);
if (dto == null)
throw new InvalidOperationException("Failed to deserialize layout string");
LayoutConverter.RestoreFromDto(manager, dto, contentResolver);
}
/// <inheritdoc/>
public void DeserializeFromStream(LayoutManager manager, Stream stream,
Func<string, IDockContent?> contentResolver)
{
if (manager == null)
throw new ArgumentNullException(nameof(manager));
if (stream == null)
throw new ArgumentNullException(nameof(stream));
var dto = JsonSerializer.Deserialize<LayoutDto>(stream, _options);
if (dto == null)
throw new InvalidOperationException("Failed to deserialize layout stream");
LayoutConverter.RestoreFromDto(manager, dto, contentResolver);
}
/// <summary>
/// Создает стандартные опции сериализации JSON.
/// </summary>
/// <returns>Экземпляр <see cref="JsonSerializerOptions"/> с настройками по умолчанию.</returns>
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
};
}
}