code/KustoCopyConsole/Entity/RowItems/RowItemSerializer.cs (96 lines of code) (raw):

using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using System.Text; using System.Text.Json; namespace KustoCopyConsole.Entity.RowItems { internal class RowItemSerializer { private readonly IImmutableDictionary<RowType, Type> _rowTypeIndex; private readonly IImmutableDictionary<Type, RowType> _typeIndex; #region Constructors public RowItemSerializer() { _rowTypeIndex = ImmutableDictionary<RowType, Type>.Empty; _typeIndex = ImmutableDictionary<Type, RowType>.Empty; } private RowItemSerializer( IImmutableDictionary<RowType, Type> rowTypeIndex, IImmutableDictionary<Type, RowType> typeIndex) { _rowTypeIndex = rowTypeIndex; _typeIndex = typeIndex; } #endregion public RowItemSerializer AddType<T>(RowType rowType) where T : RowItemBase { var type = typeof(T); return new RowItemSerializer( _rowTypeIndex.Add(rowType, type), _typeIndex.Add(type, rowType)); } #region Serialize public string Serialize(RowItemBase item) { if (_typeIndex.TryGetValue(item.GetType(), out var rowType)) { var itemText = JsonSerializer.Serialize( item, RowItemJsonContext.Default.GetTypeInfo(item.GetType())!); var wrapperText = @$"{{ ""rowType"" : ""{rowType}"", ""row"" : {itemText} }}"; return wrapperText + '\n'; } else { throw new NotSupportedException( $"Row type {item.GetType().Name} isn't supported"); } } #endregion #region Deserialize public RowItemBase Deserialize(string text) { var document = JsonDocument.Parse(text); if (document.RootElement.TryGetProperty("rowType", out var rowTypeElement)) { var rowTypeText = rowTypeElement.GetString()!; if (Enum.TryParse<RowType>(rowTypeText, out var rowType)) { var rowItemType = _rowTypeIndex[rowType]; if (document.RootElement.TryGetProperty("row", out var rowElement)) { var rowElementText = rowElement.GetRawText(); var itemObject = JsonSerializer.Deserialize( rowElementText, RowItemJsonContext.Default.GetTypeInfo(rowItemType)!); if (itemObject != null) { return (RowItemBase)itemObject; } else { throw new InvalidDataException( $"Can't deserialize row: {rowElement.GetRawText()}"); } } else { throw new InvalidDataException($"Expected a property 'rowType': {text}"); } } else { throw new InvalidDataException($"Unexpected 'rowType': '{rowTypeText}'"); } } else { throw new InvalidDataException($"Expect 'rowType' JSON Property: {text}"); } } #endregion } }