https://kotlinlang.org logo
#announcements
Title
# announcements
r

Remy Benza

01/16/2021, 12:19 PM
Is there a way of serializing a
MutableList<Pair<Pair<String, Boolean>, Triple<String, String, Boolean>>>
type with the kotlinx serialization lib without writing a custom type converter?
Trying to insert this list in an Android room database
I've red the docs but seems like
.encodeToString()
won't work in this case
n

nfrankel

01/16/2021, 2:04 PM
i don't know but it's a complex type wouldn't it make sense to create a dedicated class with a serializer for rhe sake of readability?
3
r

Remy Benza

01/16/2021, 2:22 PM
How would you approach this? The list is a week schedule, an item is like; monday, true/false, 09:00, 17:00, true/false
Just map it to a list of strings? Then you would loose index
j

jbnizet

01/16/2021, 4:34 PM
I don’t know anything about kotlinx serialization, but by reading the type
MutableList<Pair<Pair<String, Boolean>, Triple<String, String, Boolean>>>
, or any code using it, there is absolutely no way of knowing what the list represents, what the pairs represent, what the strings and the booleans represent. Even with your example, it’s not quite easy to figure out. If you had a class
WeeklySchedule
, containing a collection (list, or map) of
Appointment
(I’m guessing here), containing a TimeInterval, and named boolean properties such as
booked
or
meetingPlanned
for example, all the code would be much easier to understand than things like
list[2].first.second
. Instead you could have
weeklyScheduled.get(TUESDAY).isBooked
. Your days shouldn’t be strings, but most probably a DayOfWeek enum instance. Your hours shouldn’t be strings but LocalTime instances. This would prevent you from storing incorrect values like “Satrday” or “25:62" in your objects.
1
n

nanodeath

01/16/2021, 4:45 PM
I'm still not sure what each part of your complex type represents, but it seems like it could almost be represented simply by
List<Period>
. that captures all the "true" values, and each Period is an intra-day timerange already.
r

Remy Benza

01/16/2021, 6:12 PM
Thanks for the replies, its quite simple. It's: day/dayIsSelected, fromTime/untilTime/isFullDay
The UI might make it more clear.
j

jbnizet

01/16/2021, 7:20 PM
So you have a WeeklySchedule. WeeklySchedule contains a list of 7 DailySchedule. A dailySchedule has a day of type DayOfWeek, and it also has a nullable TimeInterval. If the TimeInterval is null, it means the daily schedule is not selected. If it’s not null, it means it is selected. The TimeInterval contains a start and an end, both of type LocalTime. If start and end are both equal to 00:00, then it means the full day is checked. You can of course have variations (use a Map<DayOfWeek, DailySchedule> for example) depending on the context and what it could impose to the design, but anyway, having well-defined classes with well-named, well-typed properties and methods is way easier to understand and maintain than having pairs of pairs of triples.
r

Remy Benza

01/16/2021, 7:35 PM
Yes, I fully agree with you there. I will refactor my codewith your suggestion
Coming back to my initial question, how would you map this to a JSON and back?
m

Matteo Mirk

01/18/2021, 11:44 AM
I absolutely back Jean-Baptiste, your initial type suffers from Primitive Obsession. It would be best to write domain-specific types. As for JSON mapping , you have to annotate your classes and maybe write a custom serializer for non-primitive fields.
r

Remy Benza

01/18/2021, 2:14 PM
This is how I eventually solved it, think it's a big improvement:
Any feedback is welcome
m

Matteo Mirk

01/18/2021, 2:58 PM
Good refactoring! I have some suggestions if you want: • since the selection is part of the UI it shouldn’t be reflected by the model, so you could eliminate the
isSelected
and
dayOfWeek
properties, and restructure your time frame as a
Map<DayOfWeek, RuleDay>
: this way only the existing mappings are those selected • in
RuleDay
you could leave separated from/until time fields, or you could merge them in a
ClosedRange<LocalTime>
having only one property that will provide you facilities to check inclusion and boundaries • |--> a “full day” flag would be represented as a 0..23 range
r

Remy Benza

01/18/2021, 3:01 PM
Thanks for your elaborate suggestions. I'll take them in consideration. How do you evaluate the TypeConverters?
m

Matteo Mirk

01/18/2021, 3:16 PM
Sadly I don’t have enough experience on kotlinx.serialization to give you an advice, but in general it seems you are doing some unnecessary work to encode the values in a pipe-separated string which could be avoided relying only on JSON conversion
13 Views