Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/Hl7.Fhir.Base/CompatibilitySuppressions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@
<Right>lib/net8.0/Hl7.Fhir.Base.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Hl7.Fhir.Introspection.BindableAttribute</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.DeepComparable</Target>
Expand All @@ -43,6 +50,13 @@
<Right>lib/net8.0/Hl7.Fhir.Base.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Hl7.Fhir.Model.ISystemAndCode</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.BaseFhirSerializer</Target>
Expand Down
52 changes: 0 additions & 52 deletions src/Hl7.Fhir.Base/Introspection/BindableAttribute.cs

This file was deleted.

6 changes: 3 additions & 3 deletions src/Hl7.Fhir.Base/Introspection/ClassMapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public static bool TryCreate(Type type, [NotNullWhen(true)]out ClassMapping? res
}

// Now continue with the normal algorithm, types adorned with the [FhirTypeAttribute]
if (GetAttribute<FhirTypeAttribute>(type.GetTypeInfo(), release) is not { } typeAttribute) return false;
if (GetAttribute<FhirTypeAttribute>(type, release) is not { } typeAttribute) return false;

result = new ClassMapping(collectTypeName(typeAttribute, type), type, release)
{
Expand All @@ -96,9 +96,9 @@ public static bool TryCreate(Type type, [NotNullWhen(true)]out ClassMapping? res
type.GenericTypeArguments[0] : null,
IsFhirPrimitive = typeof(PrimitiveType).IsAssignableFrom(type),
IsBackboneType = typeAttribute.IsBackboneType,
IsBindable = GetAttribute<BindableAttribute>(type.GetTypeInfo(), release)?.IsBindable ?? false,
IsBindable = typeof(ICoded).IsAssignableFrom(type),
Canonical = typeAttribute.Canonical,
ValidationAttributes = GetAttributes<ValidationAttribute>(type.GetTypeInfo(), release).ToArray(),
ValidationAttributes = GetAttributes<ValidationAttribute>(type, release).ToArray(),
};

return true;
Expand Down
30 changes: 14 additions & 16 deletions src/Hl7.Fhir.Base/Model/Code.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,24 +30,22 @@ POSSIBILITY OF SUCH DAMAGE.

#nullable enable

using Hl7.Fhir.Introspection;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace Hl7.Fhir.Model
namespace Hl7.Fhir.Model;

public partial class Code : ICoded
{
[Bindable(true)]
public partial class Code
{
/// <summary>
/// Creates a <see cref="ElementModel.Types.Code"/> from an instance of a <see cref="Code"/>.
/// </summary>
public virtual ElementModel.Types.Code ToSystemCode() => new(system: null, code: Value, display: null, version: null);
/// <summary>
/// Creates a <see cref="ElementModel.Types.Code"/> from an instance of a <see cref="Code"/>.
/// </summary>
public virtual ElementModel.Types.Code ToSystemCode() => new(system: null, code: Value, display: null, version: null);

/// <summary>
/// Checks whether the given literal is correctly formatted.
/// </summary>
public static bool IsValidValue(string value) => Regex.IsMatch(value, "^" + PATTERN + "$", RegexOptions.Singleline);
}
}
/// <summary>
/// Checks whether the given literal is correctly formatted.
/// </summary>
public static bool IsValidValue(string value) => Regex.IsMatch(value, "^" + PATTERN + "$", RegexOptions.Singleline);

#nullable restore
public virtual IEnumerable<Coding> ToCodings() => [new(system: null, code: Value)];
}
118 changes: 57 additions & 61 deletions src/Hl7.Fhir.Base/Model/CodeOfT.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ POSSIBILITY OF SUCH DAMAGE.

*/

#nullable enable

using Hl7.Fhir.Introspection;
using Hl7.Fhir.Specification;
Expand All @@ -40,81 +41,76 @@ POSSIBILITY OF SUCH DAMAGE.
using COVE = Hl7.Fhir.Validation.CodedValidationException;
using S = Hl7.Fhir.ElementModel.Types;

namespace Hl7.Fhir.Model
namespace Hl7.Fhir.Model;

/// <summary>
/// A <see cref="Code"/> that has a limited set of values and which <see cref="Code.Value"/> can therefore
/// be represented as an enumerated type.
/// </summary>
[Serializable]
[FhirType("codeOfT")]
[DataContract]
[System.Diagnostics.DebuggerDisplay(@"\{Value={Value}}")]
public class Code<T> : Code, INullableValue<T> where T : struct, Enum
{
/// <summary>
/// A <see cref="Code"/> that has a limited set of values and which <see cref="Code.Value"/> can therefore
/// be represented as an enumerated type.
/// </summary>
[Serializable]
[FhirType("codeOfT")]
[DataContract]
[System.Diagnostics.DebuggerDisplay(@"\{Value={Value}}")]
public class Code<T> : Code, INullableValue<T>, ISystemAndCode where T : struct, Enum
static Code()
{
static Code()
{
if (!typeof(T).IsEnum())
throw new ArgumentException("T must be an enumerated type");
}
if (!typeof(T).IsEnum())
throw new ArgumentException("T must be an enumerated type");
}

public override string TypeName => "code";
public override string TypeName => "code";

public Code() : this(null) { }
public Code() : this(null) { }

public Code(T? value)
{
Value = value;
}
public Code(T? value)
{
Value = value;
}

// Primitive value of element
[FhirElement("value", IsPrimitiveValue = true, XmlSerialization = XmlRepresentation.XmlAttr, InSummary = true, Order = 30)]
[DataMember]
new public T? Value
// Primitive value of element
[FhirElement("value", IsPrimitiveValue = true, XmlSerialization = XmlRepresentation.XmlAttr, InSummary = true, Order = 30)]
[DataMember]
new public T? Value
{
get => TryParseObjectValue(out var value)
? value
: throw new InvalidCastException($"Value '{ObjectValue}' cannot be cast to a member of enumeration {typeof(T).Name}.");
set
{
get => TryParseObjectValue(out var value)
? value
: throw new InvalidCastException($"Value '{ObjectValue}' cannot be cast to a member of enumeration {typeof(T).Name}.");
set
{
ObjectValue = value?.GetLiteral();
OnPropertyChanged("Value");
}
ObjectValue = value?.GetLiteral();
OnPropertyChanged("Value");
}
}

internal bool TryParseObjectValue(out T? value)
{
value = default;

internal bool TryParseObjectValue(out T? value)
if (ObjectValue is string s && EnumUtility.ParseLiteral<T>(s) is { } parsed)
{
value = default;

if (ObjectValue is string s && EnumUtility.ParseLiteral<T>(s) is { } parsed)
{
value = parsed;
return true;
}
else return ObjectValue is null;
value = parsed;
return true;
}
else return ObjectValue is null;
}

string ISystemAndCode.System => Value?.GetSystem();
public override IEnumerable<Coding> ToCodings() => [new(Value?.GetSystem(), Value?.GetLiteral())];

string ISystemAndCode.Code => Value?.GetLiteral();
public override S.Code ToSystemCode() =>
new(Value?.GetSystem(),
Value?.GetLiteral() ?? throw new InvalidOperationException("Code must have a value in order to be useable to construct a System.Code."),
display: null,
version: null);

public override S.Code ToSystemCode() =>
new(Value?.GetSystem(),
Value?.GetLiteral() ?? throw new InvalidOperationException("Code must have a value in order to be useable to construct a System.Code."),
display: null,
version: null);
public override IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var baseResults = base.Validate(validationContext);

public override IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var baseResults = base.Validate(validationContext);

if (TryParseObjectValue(out _))
return baseResults;
else
{
var result = COVE.INVALID_CODED_VALUE(validationContext, ObjectValue, EnumUtility.GetName<T>()).AsResult(validationContext);
return baseResults.Append(result);
}
}
if (TryParseObjectValue(out _))
return baseResults;

var result = COVE.INVALID_CODED_VALUE(validationContext, ObjectValue, EnumUtility.GetName<T>()).AsResult(validationContext);
return baseResults.Append(result);
}
}
21 changes: 11 additions & 10 deletions src/Hl7.Fhir.Base/Model/CodeableConcept.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,21 @@ POSSIBILITY OF SUCH DAMAGE.

*/

using Hl7.Fhir.Introspection;
#nullable enable

using System.Collections.Generic;
using System.Linq;
using S = Hl7.Fhir.ElementModel.Types;

namespace Hl7.Fhir.Model;

namespace Hl7.Fhir.Model
public partial class CodeableConcept : ICoded
{
[Bindable(true)]
public partial class CodeableConcept
public S.Concept ToSystemConcept()
{
public S.Concept ToSystemConcept()
{
var codes = Coding.Select(c => c.ToSystemCode());
return new S.Concept(codes, display: Text);
}
var codes = Coding.Select(c => c.ToSystemCode());
return new S.Concept(codes, display: Text);
}
}

public IEnumerable<Coding> ToCodings() => Coding;
}
33 changes: 17 additions & 16 deletions src/Hl7.Fhir.Base/Model/CodeableReference.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,27 @@
*/

#nullable enable
using Hl7.Fhir.Introspection;

namespace Hl7.Fhir.Model
using System.Collections.Generic;

namespace Hl7.Fhir.Model;

public partial class CodeableReference : ICoded
{
[Bindable(true)]
public partial class CodeableReference
public CodeableReference()
{
public CodeableReference()
{
// Nothing
}
// Nothing
}

public CodeableReference(CodeableConcept concept)
{
Concept = concept;
}
public CodeableReference(CodeableConcept concept)
{
Concept = concept;
}

public CodeableReference(ResourceReference reference)
{
Reference = reference;
}
public CodeableReference(ResourceReference reference)
{
Reference = reference;
}

public IEnumerable<Coding> ToCodings() => Concept?.ToCodings() ?? [];
}
Loading