1+ // Copyright (c) Microsoft Corporation. All rights reserved.
2+ // Licensed under the MIT license.
3+
4+ using System . Collections . Generic ;
5+ using System . Linq ;
6+ using Microsoft . OpenApi . Interfaces ;
7+
8+ namespace Microsoft . OpenApi . Services
9+ {
10+ /// <summary>
11+ /// Defines behavior for comparing <see cref="IDictionary{TKey,TValue}"/> where TKey is <see cref="string"/>
12+ /// and TValue is <see cref="IOpenApiSerializable"/>.
13+ /// </summary>
14+ public class OpenApiDictionaryComparer < T > : OpenApiComparerBase < IDictionary < string , T > >
15+ where T : IOpenApiSerializable
16+ {
17+ /// <summary>
18+ /// Executes comparision against source and target <see cref="IDictionary{TKey, TValue}"/>
19+ /// where TKey is <see cref="string"/> and TValue is <see cref="IOpenApiSerializable"/>.
20+ /// </summary>
21+ /// <param name="sourceFragment">The source.</param>
22+ /// <param name="targetFragment">The target.</param>
23+ /// <param name="comparisonContext">Context under which to compare the source and target.</param>
24+ public override void Compare (
25+ IDictionary < string , T > sourceFragment ,
26+ IDictionary < string , T > targetFragment ,
27+ ComparisonContext comparisonContext )
28+ {
29+ if ( sourceFragment == null && targetFragment == null )
30+ {
31+ return ;
32+ }
33+
34+ if ( sourceFragment == null || targetFragment == null )
35+ {
36+ comparisonContext . AddOpenApiDifference (
37+ new OpenApiDifference
38+ {
39+ OpenApiDifferenceOperation = OpenApiDifferenceOperation . Update ,
40+ SourceValue = sourceFragment ,
41+ TargetValue = targetFragment ,
42+ OpenApiComparedElementType = typeof ( IDictionary < string , T > ) ,
43+ Pointer = comparisonContext . PathString
44+ } ) ;
45+
46+ return ;
47+ }
48+
49+ var newKeysInTarget = targetFragment . Keys . Except ( sourceFragment . Keys ) . ToList ( ) ;
50+
51+ foreach ( var newKeyInTarget in newKeysInTarget )
52+ {
53+ WalkAndAddOpenApiDifference (
54+ comparisonContext ,
55+ newKeyInTarget ,
56+ new OpenApiDifference
57+ {
58+ OpenApiDifferenceOperation = OpenApiDifferenceOperation . Add ,
59+ TargetValue = new KeyValuePair < string , T > (
60+ newKeyInTarget ,
61+ targetFragment [ newKeyInTarget ] ) ,
62+ OpenApiComparedElementType = typeof ( KeyValuePair < string , T > )
63+ } ) ;
64+ }
65+
66+ foreach ( var source in sourceFragment )
67+ {
68+ if ( targetFragment . Keys . Contains ( source . Key ) )
69+ {
70+ WalkAndCompare ( comparisonContext , source . Key ,
71+ ( ) => comparisonContext
72+ . GetComparer < T > ( )
73+ . Compare ( source . Value , targetFragment [ source . Key ] , comparisonContext ) ) ;
74+ }
75+ else
76+ {
77+ WalkAndAddOpenApiDifference (
78+ comparisonContext ,
79+ source . Key ,
80+ new OpenApiDifference
81+ {
82+ OpenApiDifferenceOperation = OpenApiDifferenceOperation . Remove ,
83+ SourceValue = source ,
84+ OpenApiComparedElementType = typeof ( KeyValuePair < string , T > )
85+ } ) ;
86+ }
87+ }
88+ }
89+ }
90+ }
0 commit comments