Closed ghostdogpr closed 2 months ago
The issue is similar to what is done in https://github.com/scalalandio/chimney/blob/master/chimney-protobufs/src/test/scala/io/scalaland/chimney/ProtobufOneOfSpec.scala#L13 - PB arbitrarily decides what to wrap and what to pass straight forcing users to wrap/unwrap in arbitrary places.
This would require change in macros which would test if something is wrapper and unwrap automatically even if the type is not an AnyVal
which is kinda ugly - I'd allow such thing only with a flag as this could generate some subtle bugs and increase the compilation time.
Maybe only check if the inner type is a scalapb.GeneratedOneof
?
I agree with you, it's quite ugly and unfortunate that scalapb doesn't give us a better way to do that 🤔
Maybe only check if the inner type is a scalapb.GeneratedOneof?
That would require making the core, dependency-free, module dependent on some external implementation. Or introducing a way of injecting extensions into makro with some type classes and implicits.
Maybe some workaround like:
implicit def transformAndWrap[
From,
To <: scalapb.GeneratedMessage,
ToValue <: scalapb.GeneratedOneof
](
implicit transformer: Transformer.AutoDerived[From, ToValue],
// shapeless.HList or Mirror.ProductOf as evidence + constructor
// e.g. Generic.Aux[To, ToValue :: HNil]
// or Mirror.ProductOf[To] { type MirrorElementTypes = ToValue +: EmptyTuple }
): Transformer[From, To] =
src => {
val value = transformer.transform(src)
// wrap value using shapeless/mirror
}
would pass in the meantime.
Released in 1.3.0
Checklist
TransformerF
s) orunsafeOption
flagsDescribe the desired behavior
Let's consider
AddressBookType
from ProtobufOneOfSpec.We can convert
addressbook.AddressBookType
intopb.addressbook.AddressBookType.Value
and vice-versa. This works great.However if
AddressBookType
is used inside another protobuf message, the Scala object for that message will have a field of typepb.addressbook.AddressBookType
, notpb.addressbook.AddressBookType.Value
. It means that it still requires a manual implicit transformer to convert that parent object.It would be great if there was a seamless transformation between the 2 corresponding types,
addressbook.AddressBookType
andpb.addressbook.AddressBookType
.Use case example
Let's add this to addressbook.proto:
And this to AddressBook.scala:
Now let's try to create a
Parent
and transform it:It fails with:
A workaround is to create a
Transformer
fromaddressbook.AddressBookType
topb.addressbook.AddressBookType
:How it relates to existing features
If there is a simpler workaround, please let me know. I have hundreds of classes from protobuf so I am trying to find a solution that doesn't involve manually defining transformers for each
oneof
.