twitter / scrooge

A Thrift parser/generator
http://twitter.github.io/scrooge/
Apache License 2.0
793 stars 247 forks source link

Feature Suggestion: Custom type adapters #342

Open tnn opened 3 years ago

tnn commented 3 years ago

When using the service defintion of the generated code, there is a mismatch between the high level types and the underlying thrift binary serialization strategy. The canonical example for Scala/Java is UUID or ZonedDateTime, leading to implementors either polluting their service traits with Int and Long's or using Strings when the customer of those APIs often would like to work in higher level types such as UUID, ZonedDateTime - or their own custom such as UserID.

There is multiple ways this could be implemented, however there seems to be an chicken-and-egg problem by the thrift definitions not yet being compiled and generated yet, when loading any custom adapter, therefore the trait for an adapter likely have to be at a lower level.

struct UUID {
    1: i64 mostSigBits;
    2: i64 leastSigBits;
} (com.twitter.scrooge.scala.customadapter = "com.example.thrift.UUIDAdapter")

struct UserID {
    1: UUID id;
} (com.twitter.scrooge.scala.customadapter = "com.example.thrift.UserIDAdapter")
class UserIDAdapter extends CustomAdapter[UserID] {
  override def fromThrift(struct: MagicMetaThrift): UserID {
    UserID.from(UUID(struct._1, struct._2))
  }
  override def toThrift(userID: UserID): MagicMetaThrift) {
    // magic serialization
  }
} 

Please let me know if this is completely off the rails or if something like this is already possible today. I would also like to reference the Java / XML solution, XmlAdapter

bonniee commented 3 years ago

Hi @tnn ,

Thanks for this suggestion. If you open a pull request, we'd be happy to review a patch for this.