Skip to content

Commit

Permalink
Merge pull request #2988 from FirelyTeam/6.0/2928-introduce-iequality…
Browse files Browse the repository at this point in the history
…comparer

Introduce IEqualityComparer instead of Matches/IsExactly
  • Loading branch information
Kasdejong authored Dec 9, 2024
2 parents fcfb244 + 6596bbf commit 5e8f100
Show file tree
Hide file tree
Showing 660 changed files with 33,267 additions and 78,437 deletions.
35 changes: 35 additions & 0 deletions src/Hl7.Fhir.Base/CompatibilitySuppressions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,20 @@
<Right>lib/net8.0/Hl7.Fhir.Base.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Hl7.Fhir.Model.DeepComparable</Target>
<Left>lib/net8.0/Hl7.Fhir.Base.dll</Left>
<Right>lib/net8.0/Hl7.Fhir.Base.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Hl7.Fhir.Model.IDeepComparable</Target>
<Left>lib/net8.0/Hl7.Fhir.Base.dll</Left>
<Right>lib/net8.0/Hl7.Fhir.Base.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Hl7.Fhir.Serialization.DefaultModelFactory</Target>
Expand Down Expand Up @@ -302,6 +316,27 @@
<Right>lib/net8.0/Hl7.Fhir.Base.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Hl7.Fhir.Model.Base.GetElementPairs</Target>
<Left>lib/net8.0/Hl7.Fhir.Base.dll</Left>
<Right>lib/net8.0/Hl7.Fhir.Base.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Hl7.Fhir.Model.Base.IsExactly(Hl7.Fhir.Model.IDeepComparable)</Target>
<Left>lib/net8.0/Hl7.Fhir.Base.dll</Left>
<Right>lib/net8.0/Hl7.Fhir.Base.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Hl7.Fhir.Model.Base.Matches(Hl7.Fhir.Model.IDeepComparable)</Target>
<Left>lib/net8.0/Hl7.Fhir.Base.dll</Left>
<Right>lib/net8.0/Hl7.Fhir.Base.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Hl7.Fhir.Model.Bundle.LinkComponent.get_RelationElement</Target>
Expand Down
2 changes: 1 addition & 1 deletion src/Hl7.Fhir.Base/ElementModel/PocoElementNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public IEnumerable<ITypedElement> Children(string name)

if (name is null)
{
return Current.GetElementPairs().SelectMany(kvp
return Current.EnumerateElements().SelectMany(kvp
=> createChildNodes(kvp.Key, kvp.Value));
}

Expand Down
2 changes: 1 addition & 1 deletion src/Hl7.Fhir.Base/ElementModel/PocoElementNode2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public record SinglePocoElementNode(Base Poco, PocoElementNode2? Parent, int? In
: PocoElementNode2(Parent, Name ?? Poco.TypeName), IScopedNode, IFhirValueProvider, IResourceTypeSupplier, IAnnotated
{
public IEnumerable<PocoElementNode2> Children() =>
Poco.GetElementPairs()
Poco.EnumerateElements()
.Select(ep =>
nodeFor(ep.Key, ep.Value)
);
Expand Down
2 changes: 1 addition & 1 deletion src/Hl7.Fhir.Base/Model/Base.Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public static class BaseExtensions
"be the same type, as they reflect the type in the actual POCO definition.")]
public static IEnumerable<Base> Children(this Base instance)
{
foreach (var element in instance.GetElementPairs())
foreach (var element in instance.EnumerateElements())
{
switch (element.Key, element.Value)
{
Expand Down
48 changes: 42 additions & 6 deletions src/Hl7.Fhir.Base/Model/Base.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ POSSIBILITY OF SUCH DAMAGE.

namespace Hl7.Fhir.Model;

public abstract partial class Base : IDeepCopyable, IDeepComparable, IAnnotatable,
public abstract partial class Base : IDeepCopyable, IAnnotatable,
IValidatableObject, INotifyPropertyChanged
{
/// <summary>
Expand Down Expand Up @@ -87,7 +87,17 @@ protected virtual void OnPropertyChanged(string property) =>

#endregion

internal protected virtual Base SetValue(string key, object? value)
/// <summary>
/// Sets the value of an element in the POCO, or, if the element is not defined, in the overflow dictionary.
/// </summary>
/// <param name="key">The name of the element.</param>
/// <param name="value">Either a <see cref="Base"/> or an <see cref="IReadOnlyList{T}"/> of <see cref="Base"/>.</param>
/// <returns>The currect object, so the calls can be chained fluently.</returns>
/// <exception cref="InvalidCastException">Thrown if the value is not a <c>Base</c> or <c>IReadOnlyList&lt;Base&gt;</c>.</exception>
/// <remarks>If the value is set to <c>null</c>, the property is set to null, or, if not defined, the
/// element is removed from the overflow dictionary. If the key refers to an existing property, the value
/// must be compatible with the type of the property in the POCO, otherwise an <see cref="InvalidCastException"/> is thrown.</remarks>
public virtual Base SetValue(string key, object? value)
{
if (value is null)
Overflow.Remove(key);
Expand All @@ -101,16 +111,42 @@ internal protected virtual Base SetValue(string key, object? value)
return this;
}

internal object this[string key]
/// <summary>
/// /// Gets the value of an element in the POCO, or, if the element is not defined, in the overflow dictionary.
/// </summary>
/// <param name="key">The name of the element.</param>
/// <returns>A <see cref="Base"/> or an <see cref="IReadOnlyList{T}"/> of <see cref="Base"/>.</returns>
/// <exception cref="KeyNotFoundException">If the element is not set, or is an empty list.</exception>
public object this[string key]
{
get => this.TryGetValue(key, out var value)
? value
: throw new KeyNotFoundException($"Element '{key}' is not a known FHIR element or has no value.");
set => SetValue(key, value);
}

internal protected virtual bool TryGetValue(string key, [NotNullWhen(true)] out object? value) =>
Overflow.TryGetValue(key, out value);
/// <summary>
/// Gets the value of an element in the POCO, or, if the element is not defined, in the overflow dictionary.
/// </summary>
/// <param name="key">The name of the element.</param>
/// <param name="value">Will be a <see cref="Base"/> or an <see cref="IReadOnlyList{T}"/> of <see cref="Base"/>.</param>
/// <returns><c>true</c> if the given value was set in the POCO or present in the overflow dictionary, <c>false</c> otherwise.
/// For lists, this means they should not be empty.</returns>
public virtual bool TryGetValue(string key, [NotNullWhen(true)] out object? value) =>
Overflow.TryGetValue(key, out value) && (value is not IReadOnlyList<Base> list || list.Count > 0);

/// <summary>
/// Enumerates all non-empty elements in the POCO and the overflow dictionary.
/// </summary>
/// <returns>A <see cref="KeyValuePair{TKey,TValue}" /> containing the key and the value, which is
/// either a <see cref="Base"/> or an <see cref="IReadOnlyList{T}"/> of <see cref="Base"/>.</returns>
public virtual IEnumerable<KeyValuePair<string, object>> EnumerateElements() => Overflow;


internal protected virtual IEnumerable<KeyValuePair<string, object>> GetElementPairs() => Overflow;
/// <summary>
/// Compare the children of this Base object with the children of another Base object using the specified comparer.
/// </summary>
/// <remarks>The <paramref name="comparer"/> must implement both <c>IEqualityComparer&lt;Base&gt;</c> and
/// <c>IEqualityComparer&lt;IEnumerable&lt;Base&gt;&gt;</c>.</remarks>
public virtual bool CompareChildren(Base other, IEqualityComparer<Base> comparer) => true;
}
62 changes: 19 additions & 43 deletions src/Hl7.Fhir.Base/Model/Generated/Attachment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -567,54 +567,30 @@ public override IDeepCopyable DeepCopy()
return CopyTo(new Attachment());
}

///<inheritdoc />
public override bool Matches(IDeepComparable other)
public override bool CompareChildren(Base other, IEqualityComparer<Base> comparer)
{
var otherT = other as Attachment;
if(otherT == null) return false;

if(!base.Matches(otherT)) return false;
if( !DeepComparable.Matches(ContentTypeElement, otherT.ContentTypeElement)) return false;
if( !DeepComparable.Matches(LanguageElement, otherT.LanguageElement)) return false;
if( !DeepComparable.Matches(DataElement, otherT.DataElement)) return false;
if( !DeepComparable.Matches(UrlElement, otherT.UrlElement)) return false;
if( !DeepComparable.Matches(SizeElement, otherT.SizeElement)) return false;
if( !DeepComparable.Matches(HashElement, otherT.HashElement)) return false;
if( !DeepComparable.Matches(TitleElement, otherT.TitleElement)) return false;
if( !DeepComparable.Matches(CreationElement, otherT.CreationElement)) return false;
if( !DeepComparable.Matches(HeightElement, otherT.HeightElement)) return false;
if( !DeepComparable.Matches(WidthElement, otherT.WidthElement)) return false;
if( !DeepComparable.Matches(FramesElement, otherT.FramesElement)) return false;
if( !DeepComparable.Matches(DurationElement, otherT.DurationElement)) return false;
if( !DeepComparable.Matches(PagesElement, otherT.PagesElement)) return false;
if(!base.CompareChildren(otherT, comparer)) return false;
if(!comparer.Equals(ContentTypeElement, otherT.ContentTypeElement)) return false;
if(!comparer.Equals(LanguageElement, otherT.LanguageElement)) return false;
if(!comparer.Equals(DataElement, otherT.DataElement)) return false;
if(!comparer.Equals(UrlElement, otherT.UrlElement)) return false;
if(!comparer.Equals(SizeElement, otherT.SizeElement)) return false;
if(!comparer.Equals(HashElement, otherT.HashElement)) return false;
if(!comparer.Equals(TitleElement, otherT.TitleElement)) return false;
if(!comparer.Equals(CreationElement, otherT.CreationElement)) return false;
if(!comparer.Equals(HeightElement, otherT.HeightElement)) return false;
if(!comparer.Equals(WidthElement, otherT.WidthElement)) return false;
if(!comparer.Equals(FramesElement, otherT.FramesElement)) return false;
if(!comparer.Equals(DurationElement, otherT.DurationElement)) return false;
if(!comparer.Equals(PagesElement, otherT.PagesElement)) return false;

return true;
}

public override bool IsExactly(IDeepComparable other)
{
var otherT = other as Attachment;
if(otherT == null) return false;

if(!base.IsExactly(otherT)) return false;
if( !DeepComparable.IsExactly(ContentTypeElement, otherT.ContentTypeElement)) return false;
if( !DeepComparable.IsExactly(LanguageElement, otherT.LanguageElement)) return false;
if( !DeepComparable.IsExactly(DataElement, otherT.DataElement)) return false;
if( !DeepComparable.IsExactly(UrlElement, otherT.UrlElement)) return false;
if( !DeepComparable.IsExactly(SizeElement, otherT.SizeElement)) return false;
if( !DeepComparable.IsExactly(HashElement, otherT.HashElement)) return false;
if( !DeepComparable.IsExactly(TitleElement, otherT.TitleElement)) return false;
if( !DeepComparable.IsExactly(CreationElement, otherT.CreationElement)) return false;
if( !DeepComparable.IsExactly(HeightElement, otherT.HeightElement)) return false;
if( !DeepComparable.IsExactly(WidthElement, otherT.WidthElement)) return false;
if( !DeepComparable.IsExactly(FramesElement, otherT.FramesElement)) return false;
if( !DeepComparable.IsExactly(DurationElement, otherT.DurationElement)) return false;
if( !DeepComparable.IsExactly(PagesElement, otherT.PagesElement)) return false;

return true;
}

internal protected override bool TryGetValue(string key, out object value)
public override bool TryGetValue(string key, out object value)
{
switch (key)
{
Expand Down Expand Up @@ -663,7 +639,7 @@ internal protected override bool TryGetValue(string key, out object value)

}

internal protected override Base SetValue(string key, object value)
public override Base SetValue(string key, object value)
{
switch (key)
{
Expand Down Expand Up @@ -712,9 +688,9 @@ internal protected override Base SetValue(string key, object value)

}

internal protected override IEnumerable<KeyValuePair<string, object>> GetElementPairs()
public override IEnumerable<KeyValuePair<string, object>> EnumerateElements()
{
foreach (var kvp in base.GetElementPairs()) yield return kvp;
foreach (var kvp in base.EnumerateElements()) yield return kvp;
if (ContentTypeElement is not null) yield return new KeyValuePair<string,object>("contentType",ContentTypeElement);
if (LanguageElement is not null) yield return new KeyValuePair<string,object>("language",LanguageElement);
if (DataElement is not null) yield return new KeyValuePair<string,object>("data",DataElement);
Expand Down
26 changes: 7 additions & 19 deletions src/Hl7.Fhir.Base/Model/Generated/BackboneElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,30 +82,18 @@ public override IDeepCopyable CopyTo(IDeepCopyable other)
return dest;
}

///<inheritdoc />
public override bool Matches(IDeepComparable other)
public override bool CompareChildren(Base other, IEqualityComparer<Base> comparer)
{
var otherT = other as BackboneElement;
if(otherT == null) return false;

if(!base.Matches(otherT)) return false;
if( !DeepComparable.Matches(ModifierExtension, otherT.ModifierExtension)) return false;
if(!base.CompareChildren(otherT, comparer)) return false;
if(!comparer.ListEquals(ModifierExtension, otherT.ModifierExtension)) return false;

return true;
}

public override bool IsExactly(IDeepComparable other)
{
var otherT = other as BackboneElement;
if(otherT == null) return false;

if(!base.IsExactly(otherT)) return false;
if( !DeepComparable.IsExactly(ModifierExtension, otherT.ModifierExtension)) return false;

return true;
}

internal protected override bool TryGetValue(string key, out object value)
public override bool TryGetValue(string key, out object value)
{
switch (key)
{
Expand All @@ -118,7 +106,7 @@ internal protected override bool TryGetValue(string key, out object value)

}

internal protected override Base SetValue(string key, object value)
public override Base SetValue(string key, object value)
{
switch (key)
{
Expand All @@ -131,9 +119,9 @@ internal protected override Base SetValue(string key, object value)

}

internal protected override IEnumerable<KeyValuePair<string, object>> GetElementPairs()
public override IEnumerable<KeyValuePair<string, object>> EnumerateElements()
{
foreach (var kvp in base.GetElementPairs()) yield return kvp;
foreach (var kvp in base.EnumerateElements()) yield return kvp;
if (ModifierExtension?.Any() == true) yield return new KeyValuePair<string,object>("modifierExtension",ModifierExtension);
}

Expand Down
26 changes: 7 additions & 19 deletions src/Hl7.Fhir.Base/Model/Generated/BackboneType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,30 +82,18 @@ public override IDeepCopyable CopyTo(IDeepCopyable other)
return dest;
}

///<inheritdoc />
public override bool Matches(IDeepComparable other)
public override bool CompareChildren(Base other, IEqualityComparer<Base> comparer)
{
var otherT = other as BackboneType;
if(otherT == null) return false;

if(!base.Matches(otherT)) return false;
if( !DeepComparable.Matches(ModifierExtension, otherT.ModifierExtension)) return false;
if(!base.CompareChildren(otherT, comparer)) return false;
if(!comparer.ListEquals(ModifierExtension, otherT.ModifierExtension)) return false;

return true;
}

public override bool IsExactly(IDeepComparable other)
{
var otherT = other as BackboneType;
if(otherT == null) return false;

if(!base.IsExactly(otherT)) return false;
if( !DeepComparable.IsExactly(ModifierExtension, otherT.ModifierExtension)) return false;

return true;
}

internal protected override bool TryGetValue(string key, out object value)
public override bool TryGetValue(string key, out object value)
{
switch (key)
{
Expand All @@ -118,7 +106,7 @@ internal protected override bool TryGetValue(string key, out object value)

}

internal protected override Base SetValue(string key, object value)
public override Base SetValue(string key, object value)
{
switch (key)
{
Expand All @@ -131,9 +119,9 @@ internal protected override Base SetValue(string key, object value)

}

internal protected override IEnumerable<KeyValuePair<string, object>> GetElementPairs()
public override IEnumerable<KeyValuePair<string, object>> EnumerateElements()
{
foreach (var kvp in base.GetElementPairs()) yield return kvp;
foreach (var kvp in base.EnumerateElements()) yield return kvp;
if (ModifierExtension?.Any() == true) yield return new KeyValuePair<string,object>("modifierExtension",ModifierExtension);
}

Expand Down
5 changes: 0 additions & 5 deletions src/Hl7.Fhir.Base/Model/Generated/Base.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,6 @@ public virtual IDeepCopyable CopyTo(IDeepCopyable other)
public virtual IDeepCopyable DeepCopy() =>
CopyTo((IDeepCopyable)Activator.CreateInstance(GetType())!);

///<inheritdoc />
public virtual bool Matches(IDeepComparable other) => other is Base;

public virtual bool IsExactly(IDeepComparable other) => other is Base;

}

}
Expand Down
Loading

0 comments on commit 5e8f100

Please sign in to comment.