英文:
How to unmarshal a BSON string value into a custom type using go-mongo-driver?
问题
我正在使用MarshalBSONValue将内部结构字段编组为自定义字符串表示形式。
我无法弄清楚如何实现逆操作UnmarshalBSONValue,以便将自定义字符串表示形式解析为内部结构。
import (
"fmt"
"testing"
"github.com/stretchr/testify/assert"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/bsontype"
)
type inner struct {
value string
}
func (i inner) MarshalBSONValue() (bsontype.Type, []byte, error) {
return bsontype.String, []byte(i.value), nil
}
// How to implement this?
//
// func (i *inner) UnmarshalBSONValue(t bsontype.Type, data []byte) error {
// ...
// }
type Outer struct {
Inner inner `bson:"inner"`
}
func TestMarshalBSON(t *testing.T) {
var outer1 = Outer{Inner: inner{value: "value"}}
doc, err := bson.Marshal(outer1)
assert.NoError(t, err)
fmt.Printf("%#v\n", string(doc)) // "\x11\x00\x00\x00\x02inner\x00value\x00"
var outer2 Outer
err = bson.Unmarshal(doc, &outer2) // error
assert.NoError(t, err)
assert.Equal(t, outer1, outer2)
}
如果有人能够为上述示例测试提供一个可行的UnmarshalBSONValue实现,我将非常感激。
英文:
I'm using MarshalBSONValue to marshal an inner struct field to a custom string representation.
I can't figure out how to implement the inverse operation, UnmarshalBSONValue, in order to parse the custom string representation into an inner struct.
import (
"fmt"
"testing"
"github.com/stretchr/testify/assert"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/bsontype"
)
type inner struct {
value string
}
func (i inner) MarshalBSONValue() (bsontype.Type, []byte, error) {
return bsontype.String, []byte(i.value), nil
}
// How to implement this?
//
// func (i *inner) UnmarshalBSONValue(t bsontype.Type, data []byte) error {
// ...
// }
type Outer struct {
Inner inner `bson:"inner"`
}
func TestMarshalBSON(t *testing.T) {
var outer1 = Outer{Inner: inner{value: "value"}}
doc, err := bson.Marshal(outer1)
assert.NoError(t, err)
fmt.Printf("%#v\n", string(doc)) // "\x11\x00\x00\x00\x02inner\x00value\x00"
var outer2 Outer
err = bson.Unmarshal(doc, &outer2) // error
assert.NoError(t, err)
assert.Equal(t, outer1, outer2)
}
I would greatly appreciate it if anyone could provide a working implementation of UnmarshalBSONValue for the example test above.
答案1
得分: 4
你可以使用bsoncore.ReadString
来解析给定的值。
func (i inner) MarshalBSONValue() (bsontype.Type, []byte, error) {
return bson.MarshalValue(i.value)
}
func (i *inner) UnmarshalBSONValue(t bsontype.Type, value []byte) error {
if t != bsontype.String {
return fmt.Errorf("无效的 bson 值类型 '%s'", t.String())
}
s, _, ok := bsoncore.ReadString(value)
if !ok {
return fmt.Errorf("无效的 bson 字符串值")
}
i.value = s
return nil
}
英文:
You can use bsoncore.ReadString
to parse the given value.
func (i inner) MarshalBSONValue() (bsontype.Type, []byte, error) {
return bson.MarshalValue(i.value)
}
func (i *inner) UnmarshalBSONValue(t bsontype.Type, value []byte) error {
if t != bsontype.String {
return fmt.Errorf("invalid bson value type '%s'", t.String())
}
s, _, ok := bsoncore.ReadString(value)
if !ok {
return fmt.Errorf("invalid bson string value")
}
i.value = s
return nil
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论