Skip to content

Instantly share code, notes, and snippets.

@conorfarrell-coats
Created February 24, 2021 09:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save conorfarrell-coats/f6a6970dd74196b3ab47a289a2dc99c9 to your computer and use it in GitHub Desktop.
Save conorfarrell-coats/f6a6970dd74196b3ab47a289a2dc99c9 to your computer and use it in GitHub Desktop.
package com.coats.d3.sap
import io.kotest.core.spec.style.StringSpec
import io.kotest.matchers.shouldBe
import kotlinx.serialization.KSerializer
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import nl.adaptivity.xmlutil.serialization.XML
import nl.adaptivity.xmlutil.serialization.XmlElement
import java.time.LocalDate
import java.time.format.DateTimeFormatter
class XmlUtilSampleTest: StringSpec() {
init {
"Can deserialize an TestDto with a zero date" {
val xml = "<ScheduleLine><DeliveryDate>00.00.0000</DeliveryDate><QuantityAvailable>25</QuantityAvailable></ScheduleLine>"
val deser = XML.decodeFromString(TestDto.serializer(), xml)
deser.deliveryDate shouldBe null
deser shouldBe TestDto(
deliveryDate = null
)
}
}
}
@Serializable
@SerialName("ScheduleLine")
data class TestDto(
@XmlElement(true)
@SerialName("DeliveryDate")
@Serializable(with = OptionalDateSerializerImpl::class)
val deliveryDate: LocalDate? = null
)
open class OptionalDateSerializer(format: String, private val nullMarker: String, private val replacement: LocalDate? = null) :
KSerializer<LocalDate?> {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("LocalDate:$format", PrimitiveKind.STRING)
private val formatter = DateTimeFormatter.ofPattern(format)
override fun serialize(encoder: Encoder, value: LocalDate?) {
encoder.encodeString(value?.format(formatter) ?: nullMarker)
}
override fun deserialize(decoder: Decoder): LocalDate? {
val dateString = decoder.decodeString()
return if (dateString.isBlank() || (dateString == nullMarker)) replacement else LocalDate.parse(dateString, formatter)
}
}
object OptionalDateSerializerImpl : OptionalDateSerializer("dd.MM.yyyy", "00.00.0000")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment