Open Laxystem opened 3 months ago
No, we currently do not support @SerialInfo-annotations used on types.
No, we currently do not support @SerialInfo-annotations used on types.
Ic. Ig this issue has now become a feature request - to support @SerialInfo
annotations on TYPE_ALIAS
es or TYPE
s.
To implement this would require updates to SerialDescriptor
(in the library) and the compiler plugin. As such it might be helpful to know what your use case is, and what your intended semantics are:
Considering that the serial descriptor is linked to the serializer what you are effectively asking for is some sort of lightweight custom serializer (there is a naming problem here as well - names are supposed to be unique, and some format rely on that fact for caching)
As such it might be helpful to know what your use case is, and what your intended semantics are:
public typealias LangString = @NonLinkedJson(wrapWithValueObject = false) @Serializable(with = LangStringSerializer::class) ImmutableMap<Locale?, ImmutableList<String>>
Because it's much more flexible than creating a value class.
If it is a generic type parameter, how are you going to expose that? There is a naming problem here as well - names are supposed to be unique, and some format rely on that fact for caching.
One could support type aliases, instead of types, and then just use the typealias' name.
An alternative would be to support an annotations parameter on SerialDescriptor(serialName: String, original: SerialDescriptor)
.
@Laxystem You can already use buildSerialDescriptor
to build fully custom descriptors (including ones that just copy from the original) - even implementing the interface works (yes I'm aware these are hidden behind experimental flags - this is out of caution, to allow for API changes, not because the feature is going to suddenly disappear). Then you can have (LinkedLangStringSerializer
and NonlinkedLangStringSerializer
)
@Laxystem You can already use
buildSerialDescriptor
to build fully custom descriptors (including ones that just copy from the original) - even implementing the interface works (yes I'm aware these are hidden behind experimental flags - this is out of caution, to allow for API changes, not because the feature is going to suddenly disappear). Then you can have (LinkedLangStringSerializer
andNonlinkedLangStringSerializer
)
Ic, thanks. I'll keep this open as a feature request though
The problem with this feature is that in case of usages like
@Serializable
class X
@Serializable
class A(val s: List<@SomeInfo X>, val e: List<@SomeOtherInfo X>)
Serial descriptor for X is not created every time, it is simply taken from X.serializer()
, because it is constructed and filled there. It is possible to come up with some technical solution to re-wrap it with some additional annotation info of course, but it is a lot of work for such a narrow-scoped feature
Serial descriptor for X is not created every time, it is simply taken from
X.serializer()
, because it is constructed and filled there. It is possible to come up with some technical solution to re-wrap it with some additional annotation info of course, but it is a lot of work for such a narrow-scoped feature
That's why I'm proposing to support type aliases and not all types.
typealias XWithInfo = @SomeInfo X
// compiles into
typealias XWithInfo = @Serializable(XWithInfoSerializer::class) X
object XWithInfoSerializer : KSerializer<X> by serializer<X>() {
override val descriptor = this@KSerializer.descriptor.withAnnotation(SomeInfo())
}
// which in turn compiles into replacing all usages of XWithInfo with @Serializable(XWithInfoSerializer::class) X
Type aliases aren't really compiled into anything, they just dissolve into thin air :) I'm not sure if it is possible to provide such substitution with a compiler plugin
Type aliases aren't really compiled into anything, they just dissolve into thin air :) I'm not sure if it is possible to provide such substitution with a compiler plugin
That's the thing, what I'm suggesting is to create custom serializers with the typealias' serial name, that way, you have no conflicts.
typealias XWithInfo = @SomeInfo X // compiles into typealias XWithInfo = @Serializable(XWithInfoSerializer::class) X
This would be like an extension of
MetaSerializable
(like the custom/serializer factory behaviour originally discussed when that annotation was introduced).object XWithInfoSerializer : KSerializer<X> by serializer<X>() { override val descriptor = this@KSerializer.descriptor.withAnnotation(SomeInfo()) }
This is not actually valid, the descriptor must have a unique serialName. I'm also not sure that the
SomeInfo
annotation needs to be attached to the type/serializer rather than the use site.
This would be like an extension of
MetaSerializable
(like the custom/serializer factory behaviour originally discussed when that annotation was introduced). Yes, that was the original idea.This is not actually valid, the descriptor must have a unique serialName. I'm also not sure that the
SomeInfo
annotation needs to be attached to the type/serializer rather than the use site.
Yes; and type aliases have a full, unique name, with the package and everything.
I've only seen documentation for
.PROPERTY
and.CLASS
.