Skip to content

Commit e6d0a33

Browse files
committed
refactor(extraction): reuse FhirPathService.toJsonElement in encodeValueForField
1 parent 2d5c2f7 commit e6d0a33

1 file changed

Lines changed: 21 additions & 84 deletions

File tree

datacapture/src/commonMain/kotlin/dev/ohs/fhir/datacapture/extraction/definition/DefinitionExtractionEngine.kt

Lines changed: 21 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -827,6 +827,8 @@ object DefinitionExtractionEngine {
827827
}
828828

829829
private fun encodeValueForField(rawValue: Any, fieldDescriptor: SerialDescriptor): JsonElement {
830+
// Promotions: bare value -> a structurally different but compatible target field.
831+
// These are shape decisions, not encodings, so they still need to live here.
830832
if (
831833
fieldDescriptor.kind == StructureKind.CLASS &&
832834
looksLikeCodeableConcept(fieldDescriptor) &&
@@ -835,7 +837,9 @@ object DefinitionExtractionEngine {
835837
return buildJsonObject {
836838
put(
837839
"coding",
838-
buildJsonArray { add(json.encodeToJsonElement(Coding.serializer(), rawValue)) },
840+
buildJsonArray {
841+
add(FhirPathService.toJsonElement(rawValue, path = fieldDescriptor.serialName))
842+
},
839843
)
840844
}
841845
}
@@ -848,91 +852,24 @@ object DefinitionExtractionEngine {
848852
return buildJsonObject { put("reference", JsonPrimitive(rawValue)) }
849853
}
850854

851-
return when (rawValue) {
852-
is String -> JsonPrimitive(rawValue)
853-
854-
is Boolean -> JsonPrimitive(rawValue)
855-
856-
is Int -> JsonPrimitive(rawValue)
857-
858-
is Long -> JsonPrimitive(rawValue)
859-
860-
is BigDecimal -> JsonPrimitive(rawValue.toString())
861-
862-
is FhirString -> JsonPrimitive(rawValue.value ?: "")
863-
864-
is dev.ohs.fhir.model.r4.Boolean -> JsonPrimitive(rawValue.value ?: false)
865-
866-
is Integer -> JsonPrimitive(rawValue.value ?: 0)
867-
868-
is Decimal -> JsonPrimitive(rawValue.value?.toString() ?: "0")
869-
870-
is Date -> JsonPrimitive(rawValue.value?.toString() ?: "")
871-
872-
is DateTime -> JsonPrimitive(rawValue.value?.toString() ?: "")
873-
874-
is Time -> JsonPrimitive(rawValue.value?.toString() ?: "")
875-
876-
is Uri -> JsonPrimitive(rawValue.value ?: "")
877-
878-
is Canonical -> JsonPrimitive(rawValue.value ?: "")
879-
880-
is Code -> JsonPrimitive(rawValue.value ?: "")
881-
882-
is Coding ->
883-
if (fieldDescriptor.kind is PrimitiveKind) {
884-
JsonPrimitive(rawValue.code?.value ?: "")
885-
} else {
886-
json.encodeToJsonElement(Coding.serializer(), rawValue)
855+
// Encode once via the shared serializer, then flatten to a sub-field if the target is
856+
// primitive. No per-type re-implementation of what toJsonElement already knows how to do.
857+
val encoded = FhirPathService.toJsonElement(rawValue, path = fieldDescriptor.serialName)
858+
859+
if (fieldDescriptor.kind is PrimitiveKind && encoded is JsonObject) {
860+
val flattenedKey =
861+
when (rawValue) {
862+
is Coding -> "code"
863+
is Reference -> "reference"
864+
is Quantity -> "value".takeIf { fieldDescriptor.serialName.endsWith(".value") }
865+
else -> null
887866
}
888-
889-
is Reference ->
890-
if (fieldDescriptor.kind is PrimitiveKind) {
891-
JsonPrimitive(rawValue.reference?.value ?: "")
892-
} else {
893-
json.encodeToJsonElement(Reference.serializer(), rawValue)
894-
}
895-
896-
is Quantity ->
897-
if (
898-
fieldDescriptor.kind is PrimitiveKind && fieldDescriptor.serialName.endsWith(".value")
899-
) {
900-
JsonPrimitive(rawValue.value?.value?.toString() ?: "")
901-
} else {
902-
json.encodeToJsonElement(Quantity.serializer(), rawValue)
903-
}
904-
905-
is CodeableConcept -> json.encodeToJsonElement(CodeableConcept.serializer(), rawValue)
906-
907-
is Identifier -> json.encodeToJsonElement(Identifier.serializer(), rawValue)
908-
909-
is HumanName -> json.encodeToJsonElement(HumanName.serializer(), rawValue)
910-
911-
is ContactPoint -> json.encodeToJsonElement(ContactPoint.serializer(), rawValue)
912-
913-
is Meta -> json.encodeToJsonElement(Meta.serializer(), rawValue)
914-
915-
is Period -> json.encodeToJsonElement(Period.serializer(), rawValue)
916-
917-
is Attachment -> json.encodeToJsonElement(Attachment.serializer(), rawValue)
918-
919-
is FhirPathDate -> JsonPrimitive(rawValue.toString())
920-
921-
is FhirPathDateTime -> JsonPrimitive(formatFhirPathDateTime(rawValue))
922-
923-
is FhirPathTime -> JsonPrimitive(formatFhirPathTime(rawValue))
924-
925-
is FhirPathQuantity ->
926-
buildJsonObject {
927-
rawValue.value?.let { put("value", JsonPrimitive(it.toString())) }
928-
rawValue.unit?.let { put("unit", JsonPrimitive(it)) }
929-
}
930-
931-
else ->
932-
error(
933-
"Unsupported value type ${rawValue::class.simpleName} for descriptor ${fieldDescriptor.serialName}"
934-
)
867+
flattenedKey?.let { key ->
868+
return encoded[key] ?: JsonPrimitive("")
869+
}
935870
}
871+
872+
return encoded
936873
}
937874

938875
private fun ensureDefinitionPathAnchor(

0 commit comments

Comments
 (0)