Search code examples
scalaprotocol-buffersscalapb

How to describe Option[FiniteDuration] in proto with scalapb


I am trying to use proto3 and scalapb, but I am unable to map FiniteDuration as well as unable to use it as Option. Can anyone please advise on the same

case class Message(id:Int , interval: Option[FiniteDuration])

Solution

  • Given that you configured your scalabp in sbt as described in installation guide

    You need to define a custom type for a field to be converted from int64, mapped by default as Long, into FiniteDuration

    For example:

    syntax="proto3";
    
    import "scalapb/scalapb.proto";
    
    option java_package = "my.app.proto";
    
    message Message {
      int32 id = 1;
      optional int64 interval = 2 [(scalapb.field).type = "scala.concurrent.duration.FiniteDuration"];
    }
    

    This will generate a case class that looks what you need.

    ScalaPB will rely on implicit resolution to compile this and apply mapping from Long to FiniteDuration. For this you need to define a scalapb.TypeMapper[Long, FiniteDuration] in package object of the same package where case class is generated, ie my.app.proto.message.

    package my.app.proto
    
    import scalapb.TypeMapper
    
    import java.util.concurrent.TimeUnit
    import scala.concurrent.duration.FiniteDuration
    
    package object message {
      implicit val finiteDuration: TypeMapper[Long, FiniteDuration] =
        TypeMapper[Long, FiniteDuration](s => FiniteDuration.apply(s, TimeUnit.MILLISECONDS))(_.toMillis)
    }