I have a format that outputs lines of content like...
# serialization
z
I have a format that outputs lines of content like
PID=1.1
I made a serializable data class to represent this
Copy code
@Serializable
data class Pid(
    val first: Digits,
    val second: Digits? = null,
)
If
second
is absent, then the period and second number are not included.
Pid("1") == PID=1
Pid("1", "1") == PID=1.1
I'm making a hand-built custom serializer, but can't figure out how the descriptor aligns to the serialization and deserialization methods. Does
second
become a substructure made up of
separator value
".1"
Is it inline? Would it be
elements[2]
of the base descriptor, or closer to
elements[1][1]
?
a
Personally I find it's usually easier to write a delegate class that matches the expected output format, and then convert to/from using Kotlin code.
for example
z
Okay, I think I understand. The domain object
Pid
is Serializable. This is what the rest of the functional code is using. There's nothing special here except for
with
specifying which serializer to use. The twist though, is that the properties from
Pid
are never actually touched by the encoder. The serializer, since it's hand built, is in control of what gets sent to the encoder. The
first
and
second
properties from
Pid
are never passed as a parameter to any
encodeX
method. Instead, a new Serializable object, the
PidDelegate
is created, whose value is the entire serialized output made up of the primitive; the whole formatted string, with the expected period and second string, in a single value. Then it's just "serialize the `PidDelegate`", and since it's just a value class for a String, what gets sent to the encoder is the plain, full, singular string value. Did I get that right?
a
yes, exactly!
❤️ 1
z
Awesome, thanks so much for the guidance Adam. I was able to incorporate your changes and come up with this, which pretty gracefully handles the value class errors during deserialization as well. Still rough, but far better than I had earlier! Here's the console output from the below > PID=123.121 > decodedLocalPid: Pid(first=Digits(nonEmptyString=NonEmptyString(string=456)), second=null) true > decodedSourcePid: Pid(first=Digits(nonEmptyString=NonEmptyString(string=456)), second=Digits(nonEmptyString=NonEmptyString(string=123))) true > java.lang.IllegalArgumentException: must not be empty > java.lang.IllegalArgumentException: must contain only ASCII digits in range 0..9
a
that looks great!