Hi All, if I have a Map<String, String>, is ...
# getting-started
a
Hi All, if I have a Map<String, String>, is there a way to automatically create a data class with fields like Int, Double, Boolean. (At the moment I have to create tons of code with very basic conversions.)
g
It's not very clear. Create a data class from map on runtime or compile time? What are you trying to achieve?
a
1. I got a Map<String, String> at runtime 2. I want to convert it to data class at runtime 3. I want to avoid a manual conversion for every field (toInt(), toBoolean() etc)
The bigger task is this (very general one): There is a CSV file with a lot of columns of simple types (String, Int, Boolean, Double). I need to convert every line in CSV file to a data class. At the moment, I use TONS of code for very simple conversions.
s
I haven't used it yet, but I think the new DataFrame library probably has a lot of tools that could help with that
g
2. As I understand you don't want to convert, you just want to deseralize to existing data class
You can use kotlinx.serialization for it
Ah, I missed CSV part. For CSV there is even already a couple of custom implementations: https://github.com/brudaswen/kotlinx-serialization-csv ( I used it before, it worked fine for my use case https://github.com/hfhbd/kotlinx-serialization-csv
@Sam Dataframe can be used to parse CSV, but it doesn't allow to parse to your existing data class though, at least I believe so It supports dynamic data class generation on runtime, but it's for scripting, it's useless for a usual program)
a
@gildor this is exactly what I want to avoid. Custom (de)serialisers means TONS of code
g
What you want to avoid?
custom desearlizer is write once, works for any data class (with compatible data type of course)
a
Code. I dot not want explicitly to implement any conversion.
g
I mean, your solution to use existing CSV to data class deserealizer which I shared above
a
I have many data classes and some of them have 50 fields
g
I think you didn't understand solution which I shared
kotlinx.serialization allows to write general desearilizer for any data, not for specific data class I even shared 2 libs which already do CSV to data class deserialization (and serialization)
a
@gildor thank you, if I only have to write one line of code, then it is exactly what I am looking for:
Copy code
val parsed = csv.decodeFromString(ListSerializer(Person.serializer()), input)
g
yes, it, how it works And even if it wouldn't exist, kotlinx.serialization allows to write custom format and custom serializer/deserializer, which works for any data class, it's exactly for what it was intended for Currently you just do manual desearlization
s
A 5 year old project of mine does exactly that: ksv4ever . I upgraded it to Kotlin to 2.2.0-RC and Gradle 8.14 a few month ago. But it's an unsupported project, from a single developer (even though the original code was used at my previous employer and I liked to code so much, that I got to opensource it. But the project was sadly abandoned some months after I left.) I've read about dataframe, and that sounds like the safer option for me. Did you check the projects KlibsIO shows you when you look for csv? (the ksv lib there has no ralation to my former employer's ksv lib)
g
@Stephan Schröder dataframe is nice by itself, but it doesn't provide you dataclasses for normal applications UPD: Ah, it actually does support! I just never seen this function before https://kotlin.github.io/dataframe/cast.html Really cool, but It also jvm only and uses reflection, but it should be also fine of course Again, it depens on use-case of course, if CSV data is used for data processing, one probably could just do not bother with data classes of course. But if CSV is just a way to read data and pass it to some separated business logic, probably it's overkill in terms of capabilities and just not very helpful tool as deserializer/mapper to data class Your library uses reflection, so it probably will ever work only for JVM. Again, it's good, just wanted to make sure that we are on the same page in terms of capabilities. What I like about kotlinx.serialization is that has no reflection on jvm and supports multiplatform. We have a great success with it in our code base
👍 1
a
@Stephan Schröder unfirtunately, I cannot use Dataframe and any other library which requires to adapt the data classes adding annotations. kotlinx-serialization-csv does a very similar stuff, but I did not manage to provide any custom deserialiser for a field.
g
> I cannot use Dataframe and any other library which requires to adapt the data classes adding annotations Why? Is it because this data class is from third party library? > but I did not manage to provide any custom deserialiser for a field. What do you mean? You don't need custom deserialiser
a
@gildor yes, data classes come from another party I do need a custom deserialiser when the parsing is not straight forward. For instance, a non-ISO date string (in CSV) must be translated to Long (in data class), or there is a collection to be parsed.
g
kotlinx.serialization supports this case, check official docs, you can add serializer for third party class, and only once
Of course you need to tell the library how to convert some non standard string to long
If you need help, I suggest to prepare an example of data and class to which you trying to deserialize it and post to #C7A1U5PTM
a
@gildor I created a ticket with my question in that proiject: https://github.com/brudaswen/kotlinx-serialization-csv/issues/24
g
It's not the best place, because this library is just extension of kotlinx.serializarion, it already have all the examples
a
I must admit, I am confused with what I am going to use...
g
All solutions which I send are already based on kotlinx.serialization
This why I saying, show your example of data and data class, post to #C7A1U5PTM to ask an advice