0

我想map以防万一从protobuf生成的类包裹在Option

case class Foo(aMap: Option[Map[String, String]])

为此,我正在尝试使用scalapb.TypeMapper

package some.wrapper
import scalapb.TypeMapper
case class StringMapWrapper(map: Map[String, String])
object StringMapWrapper {
  implicit val mapper = TypeMapper(StringMapWrapper.apply)(_.map)
}

原型文件如下所示:

syntax = "proto3";
package some;
import "scalapb/scalapb.proto";
message Foo {
  map<string, string> a_map = 1 [(scalapb.field).type = "some.wrapper.StringMapWrapper"];
}

但是在编译过程中我有一个错误: --scala_out: some.Foo.a_map: Field a_map is a map and has type specified. Use key_type or value_type instead.

我该如何解决这个错误?

4

1 回答 1

1

ScalaPB 中获取 Option 内容的标准方法是将其包装在消息中:

syntax = "proto3";
package some;
import "scalapb/scalapb.proto";

message OptionalMap {
  option (scalapb.message).type = "Map[String, String]";
  map<string, string> inner = 1;
}

message UseCase {
  OptionalMap my_map = 1;
}

由于type选项 on OptionalMap,ScalaPB 将生成 myMap 作为Option[Map[String, String]]而不是Option[OptionalMap]. 那么我们唯一需要做的就是提供一个 TypeMapper 来教 ScalaPB 在 OptionalMap 和 Map[String, String] 之间进行转换。为此,请将以下内容添加到包对象UseCase所在的位置:

package object some {
  implicit val OptionalMapMapper =
      scalapb.TypeMapper[some.myfile.OptionalMap, Map[String, String]](_.inner)(some.myfile.OptionalMap(_))
}
于 2019-05-15T02:17:31.263 回答