-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Find a way to not depend on runtime reflection #1
Comments
I would really like to have a multiplatform solution without using kotlin-reflect. So does this approach require the classes to be annotated with |
Yeah, this solution would require |
Most of the time you are not in charge of the data class component to annotate... what if data classes contains other classes from third party deps? |
I see logging as a hassle-free way to print debug information. Being forced to annotate my data classes with |
Turns out kotlinx-serialization has a way to do that. If it's a simple Kotlin class with a properties-only constructor (i.e. all data classes are this way as far as I know) you can just do: // NOT @Serializable
class ClassThatIDontControl(val foo: String, val bar: Int)
@Serializer(forClass = ClassIDontControl::class)
object ClassIDontControlSerializer
// Then the pprint API would look something like this
val instance = ClassIDontControl("hello", 123)
println(pprint(ClassIDontControlSerializer, instance)) Have a look here for info. Now if the // Imagine this is coming from some 3rd-party dependency
public class ClassIDontControl {
private String foo;
private Int bar;
public String getFoo { return foo; }
public String getBar { return bar; }
// blah blah blah constructors, initializers, etc...
} // Then in your application you'd do...
class ClassIDoControl(foo: String, bar: Int)
class ClassIDontControlSerializer : KSerializer<ClassIDontControl> {
private val delegateSerializer = ClassIDoControl.serializer()
override val descriptor = SerialDescriptor("ClassIDontControl", delegateSerializer.descriptor)
override fun serialize(encoder: Encoder, value: ClassIDontControl) {
val data = ClassIDoControl(value.getFoo(), value.getBar())
encoder.encodeSerializableValue(delegateSerializer, data)
}
override fun deserialize(decoder: Decoder): ClassIDontControl {
val data: ClassIDoControl = decoder.decodeSerializableValue(delegateSerializer)
return ClassIDontControl.constructWhateverWayYouNeed(data.foo, data.bar)
}
}
@Serializer(forClass = ClassThatIDontControl::class)
object ClassIDontControlSerializer
// Then the pprint API would look something like this
val instance: ClassIDontControl = getItFromWhereverYouNeed(...)
println(pprint(ClassIDontControlSerializer, instance)) You can learn more about delegating serializers here. Bottom line, it's doable. The mighty kotlinx-serialization people have thought about these use-cases. |
I'm sorry I should have clarified this -- we're aware that it is doable, but the effort needed to make them serializable can be non-trivial which will discourage us from using I'm a mobile developer so my experience may be different from other platforms, but I've never seen anyone check-in Plus what happens to projects that use libraries other than |
I’m confused. Do you want to use kotlin-reflect, moshi, or something else? |
I'm suggesting to continue using reflection. |
I won't remove any of the current reflection-based functionality. I'll add a new module (probably |
Sounds superb! |
This library uses kotlin-reflect in the Walker in order to recursively get properties from each class as well as the class names. This functionality can be replaced with kotlinx-serialization functionality fairly easily. I have a branch that does exactly this. Can develop this further if there is an ask.
https://github.com/deusaquilus/pprint-kotlin/tree/using-kotlinx-serialization
The text was updated successfully, but these errors were encountered: