147 lines
5.7 KiB
C#
147 lines
5.7 KiB
C#
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
|
||
};
|
||
}
|
||
} |