使用oneOf protobuf字段将yaml反序列化为proto3

3

我可以帮您翻译与IT技术相关的内容。以下是需要翻译的内容:

我有一个原型消息,其结构如下:

syntax = "proto3";

message Bar {
  int64 id = 1;
  string name = 2;
  int64 value = 3;
}

message Msg {
  int32 baz = 1;
  oneof some_union {
     string foo = 2;
     Bar bar = 3;
  }
}

我可以想到两种方法来编写消息的yaml等价物。 在第一种方法中,如下示例所示,它将"some_union": null分配给字段“foo”中未设置任何值。
baz: 0
foo: "some_string"

在第二种方法中,如下面的例子所示,它会抛出一个错误,指出无法将对象解组为Go结构体字段
baz: 0
some_union:
  foo: "some_string"


我正在使用github.com/ghodss/yaml包将yaml转换为proto消息。

1
你的 baz 定义是一个 string 类型,但你正在将一个整数转换为它。 - undefined
@colm.anseo 这只是一个问题,因为使用了 github.com/ghodss/yaml。YAML本身对将 0 解析为字符串并直接使用go-yaml解析是没有问题的。然而,这个包装器首先将输入转换为JSON,其中 0 总是被解析为整数,导致了错误发生。 - undefined
对于误解我感到抱歉。我已经更新了问题。让baz是一个整数。问题出在foo字段上,它是一个oneOf类型,并且不允许yaml进行结构转换。 - undefined
您还没有共享 FooBar 的消息定义。 - undefined
我已经更新了问题,提到了fooBar的定义。但是我不认为这会有太大帮助,问题在于我无法为任何属于oneOf类型的字段设置值。 - undefined
1个回答

3

简短概述;

使用 protojson.Unmarshal 可以正确地获取一个 oneOf 字段的值。


我创建了以下的 proto 定义:

message Person {
  string name = 1;
  int32 id = 2;
  string email = 3;
  oneof avatar {
    string imageUrl = 4;
    bytes imageData = 5;
  }
}

然后我能够创建一个 YAML 文件,像这样读取正确。
---
name: Harry Potter
id: 1
email: harry@potter.com
imageUrl: https://picsum.photos/id/1005/200

唯一的问题是,如果我执行以下操作:
yamlBytes, _ := ioutil.ReadFile("testdata/person.yaml")
person := &pb.Person{}
yaml.Unmarshal(yamlBytes, person)
imageUrl的值未设置,就像您提到的那样。
您需要执行以下操作-首先将YAML转换为JSON,然后使用protojson.Unmarshal
yamlBytes, _ := ioutil.ReadFile("testdata/person.yaml")
person := &pb.Person{}
jsonBytes, _ := yaml.YAMLToJSON(yamlBytes)
protojson.Unmarshal(jsonBytes, person)

如果您正确设置了imageUrl的值,则可以使用该链接。这是完整代码的链接- https://github.com/mbtamuli/GoLearnGo/tree/master/protobufs。您可以在此处查看其操作示例- https://replit.com/@mbtamuli/didactic-train


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接