@@ -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