using System; using System.Collections.Generic; using System.Text; using System.Text.Json; namespace Quadarax.Foundation.Core.Json.Extensions { public static class JsonDocumentExt { public static IDictionary Diff(this JsonDocument src, JsonDocument trg) { if (src == null) throw new ArgumentNullException(nameof(src)); if (trg == null) throw new ArgumentNullException(nameof(trg)); var result = new Dictionary(); var srcEnumerator = src.RootElement.EnumerateObject(); var trgEnumerator = trg.RootElement.EnumerateObject(); while (srcEnumerator.MoveNext()) { var srcProperty = srcEnumerator.Current; var trgProperty = Find(srcProperty.Name, trgEnumerator.GetEnumerator()); if (trgProperty == null) result.Add(srcProperty.Name, new DiffOccurrence(srcProperty.Name, DiffTypeEnum.TrgMissing, srcProperty.Value.GetRawText(), null)); else if (!string.Equals(srcProperty.Value.GetRawText(), trgProperty.Value.Value.GetRawText(),StringComparison.InvariantCultureIgnoreCase)) result.Add(srcProperty.Name, new DiffOccurrence(srcProperty.Name, DiffTypeEnum.Different, srcProperty.Value.GetRawText(), trgProperty.Value.Value.GetRawText())); } while (trgEnumerator.MoveNext()) { var trgProperty = trgEnumerator.Current; var srcProperty = Find(trgProperty.Name, srcEnumerator.GetEnumerator()); if (srcProperty == null) { result.Add(trgProperty.Name, new DiffOccurrence(trgProperty.Name, DiffTypeEnum.SrcMissing, null, trgProperty.Value.ToString())); } } return result; } private static JsonProperty? Find(string name, IEnumerator enumerator) { while (enumerator.MoveNext()) { var property = enumerator.Current; if (property.Name.Equals(name,StringComparison.InvariantCultureIgnoreCase)) return property; } return null; } #region *** Nested classes *** public class DiffOccurrence { public string Name { get; private set; } public DiffTypeEnum DiffType { get; private set; } public string? SrcValue { get; private set; } public string? TrgValue { get; private set; } public DiffOccurrence(string name, DiffTypeEnum diffType, string? srcValue, string? trgValue) { if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name)); Name = name; DiffType = diffType; SrcValue = srcValue; TrgValue = trgValue; } public override string ToString() { var sb = new StringBuilder(); sb.Append("Name=").Append(Name).Append(";DiffType=").Append(DiffType); return sb.ToString(); } } public enum DiffTypeEnum { SrcMissing, TrgMissing, Different } #endregion } }