diff --git a/anbs_cp/Classes/KeyValueList.cs b/anbs_cp/Classes/KeyValueList.cs index 2a2e326..3f6da5c 100644 --- a/anbs_cp/Classes/KeyValueList.cs +++ b/anbs_cp/Classes/KeyValueList.cs @@ -1,5 +1,6 @@ using System.Collections; +using anbs_cp.Interfaces; using anbs_cp.Structs; namespace anbs_cp.Classes; @@ -10,7 +11,7 @@ namespace anbs_cp.Classes; /// Тип ключа /// Тип значения // ReSharper disable once ClassCanBeSealed.Global -public class KeyValueList: IEnumerable> +public class KeyValueList: IEnumerable>, ISerializable { /// /// Хранение значений @@ -171,4 +172,42 @@ public class KeyValueList: IEnumerable> /// IEnumerator IEnumerable.GetEnumerator () => GetEnumerator(); #endregion + + #region Реализация интерфейса ISerializable + /// + public string Serialize () + { + // Создаю результат + List result = []; + + // Добавляю сериализованные значения + result.AddRange(_list.Select(static item => item.Serialize())); + + // Вывожу результат + return new SysTextSerializer().Serialize(result); + } + + /// + public void Deserialize (string json) + { + // Создаю результат + List result = new SysTextSerializer().Deserialize>(json) ?? []; + + // Очищаю список + _list.Clear(); + + // Пробегаю все значения + foreach (string itemString in result) + { + // - создаю новое значение + KeyValue item = new(); + + // - десериализую в него элемента + item.Deserialize(itemString); + + // - добавляю получившееся в список + _list.Add(item); + } + } + #endregion } \ No newline at end of file diff --git a/anbs_cp/Enums/ESerializeExceptionAction.cs b/anbs_cp/Enums/ESerializeExceptionAction.cs new file mode 100644 index 0000000..600c4d0 --- /dev/null +++ b/anbs_cp/Enums/ESerializeExceptionAction.cs @@ -0,0 +1,17 @@ +namespace anbs_cp.Enums; + +/// +/// Действие, которое привело к ошибке сериализации +/// +public enum ESerializeExceptionAction +{ + /// + /// Сериализация + /// + Serialize = 0, + + /// + /// Десериализация + /// + Deserialize = 1 +} \ No newline at end of file diff --git a/anbs_cp/Exceptions/SerializeException.cs b/anbs_cp/Exceptions/SerializeException.cs new file mode 100644 index 0000000..ca99173 --- /dev/null +++ b/anbs_cp/Exceptions/SerializeException.cs @@ -0,0 +1,28 @@ +using anbs_cp.Enums; + +namespace anbs_cp.Exceptions; + +/// +/// Ошибка (де)сериализации +/// +/// Действие сериализатора, приведшее к ошибке +/// Объект сериализации при сериализации или строка json при десериализации +/// Сообщение пользователю +public sealed class SerializeException (ESerializeExceptionAction action, string? objectJson, string? message = null) + : Exception(message) +{ + /// + /// Действие сериализатора, приведшее к ошибке + /// + public ESerializeExceptionAction Action => action; + + /// + /// Объект сериализации (при action == ESerializeExceptionAction.Serialize) + /// + public string? Object => action == ESerializeExceptionAction.Serialize ? objectJson : null; + + /// + /// Строка json при десериализации + /// + public string? Json => action == ESerializeExceptionAction.Deserialize ? objectJson : null; +} \ No newline at end of file diff --git a/anbs_cp/Interfaces/ISerializable.cs b/anbs_cp/Interfaces/ISerializable.cs index 0ef7d8a..b02c149 100644 --- a/anbs_cp/Interfaces/ISerializable.cs +++ b/anbs_cp/Interfaces/ISerializable.cs @@ -1,4 +1,6 @@ -namespace anbs_cp.Interfaces; +using anbs_cp.Exceptions; + +namespace anbs_cp.Interfaces; /// /// Интерфейс для сериализации объектов @@ -9,11 +11,13 @@ public interface ISerializable /// Сериализовать элемент в формат json /// /// Строка в формате json + /// Ошибка при сериализации string Serialize(); /// /// Восстановить элемент из формата json /// /// Строка в формате json + /// Ошибка при десериализации void Deserialize(string json); } \ No newline at end of file diff --git a/anbs_cp/Structs/KeyValue.cs b/anbs_cp/Structs/KeyValue.cs index a343987..b5108ba 100644 --- a/anbs_cp/Structs/KeyValue.cs +++ b/anbs_cp/Structs/KeyValue.cs @@ -1,23 +1,29 @@ -namespace anbs_cp.Structs; +using anbs_cp.Classes; +using anbs_cp.Enums; +using anbs_cp.Exceptions; + +using ISerializable = anbs_cp.Interfaces.ISerializable; + +namespace anbs_cp.Structs; /// -/// Пара ключ-значение +/// Пара ключ-значение /// /// Тип ключа /// Тип значения /// Ключ /// Значение -public struct KeyValue(TK key, TV? value) +public struct KeyValue (TK key, TV? value): ISerializable { #region Свойства /// - /// Ключ + /// Ключ /// public TK Key { get; set; } = key; /// - /// Значение + /// Значение /// public TV? Value { get; set; } = value; @@ -26,10 +32,56 @@ public struct KeyValue(TK key, TV? value) #region Методы /// - /// Получает ключ-значение по умолчанию + /// Получает ключ-значение по умолчанию /// /// Ключ-значение по умолчанию - public static KeyValue GetDefault() => new(); + public static KeyValue GetDefault () => new(); + + #endregion + + #region Реализация интерфейса ISerializable + /// + public readonly string Serialize () + { + // Получаю serialized-значение ключа + string keySerialized = new SysTextSerializer().Serialize(Key); + + // Исключаю из этого значения = (заменяя на %EQ%) + keySerialized = keySerialized.Replace("=", "%EQ%"); + + // Получаю serialized-значение значения + string valueSerialized = new SysTextSerializer().Serialize(Value); + + // Исключаю из этого значения = (заменяя на %EQ%) + valueSerialized = valueSerialized.Replace("=", "%EQ%"); + + // Вывожу результат + return $"{keySerialized}={valueSerialized}"; + } + + /// + public void Deserialize (string json) + { + // Разделяю сериализованную строку вида КЛЮЧ=ЗНАЧЕНИЕ на ключ и значение + string[] splited = json.Split('='); + + // Проверяю количество частей (должно быть 2) + if (splited.Length != 2) + throw new SerializeException(ESerializeExceptionAction.Deserialize, json, + "Неверное количество частей! Наверное, лишнее =?"); + + // Получаю сериализованное представление ключа + string keySerialized = splited[0].Replace("%EQ%", "="); + + // Получаю сериализованное представление значения + string valueSerialized = splited[1].Replace("%EQ%", "="); + + // Десериализую ключ + Key = (new SysTextSerializer().Deserialize(keySerialized) ?? default(TK))!; + + // Десериализую значение + Value = new SysTextSerializer().Deserialize(valueSerialized); + } #endregion } \ No newline at end of file diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index e328ba3..adf2524 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net8.0 - 2024.2.6.1 + 2024.2.11 Александр Бабаев Набор компонентов ANB Software Библиотека полезных методов языка C# @@ -22,6 +22,7 @@ 6.0 git True + Библиотека полезных методов и классов от ANB diff --git a/anbsoftware.componentspack.sln.DotSettings b/anbsoftware.componentspack.sln.DotSettings index 3006323..f318569 100644 --- a/anbsoftware.componentspack.sln.DotSettings +++ b/anbsoftware.componentspack.sln.DotSettings @@ -23,6 +23,7 @@ True True True + True True True True @@ -31,9 +32,12 @@ True True True + True True True True + True + True True True True