为 Bson.M mongodb 创建自定义 mashler/unmashler 时出错
Error when creating a custom mashler/unmashler for Bson.M mongodb
尝试为 bson.M
创建自定义 mashler/unmashler 时出现错误 WriteValueBytes can only write while positioned on a Element or Value but is positioned on a TopLevel
我有一个名为 TransactionId 的自定义类型,它表示一个 UUID 我想在存储到 monbodb 之前将此值转换为字符串,并在从 mongodb 提取值时将其从字符串转换回。
这是我目前的代码
package main
import (
"github.com/google/uuid"
"github.com/pkg/errors"
"go.mongodb.org/mongo-driver/bson/bsontype"
"go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
"go.mongodb.org/mongo-driver/bson"
"log"
)
// TransactionID is a UUID used to trace a batch of work which is being processed.
type TransactionID uuid.UUID
// String returns the transaction id as a string
func (id TransactionID) String() (result string, err error) {
val, err := uuid.FromBytes(id[:])
if err != nil {
return result, errors.Wrapf(err, "cannot convert transaction ID %s to UUID", string(id[:]))
}
return val.String(), nil
}
func (id TransactionID) MarshalBSONValue() (bsontype.Type, []byte, error) {
idString, err := id.String()
if err != nil {
return bsontype.String, nil, err
}
return bsontype.String, bsoncore.AppendString(nil, idString), nil
}
func (id *TransactionID) UnmarshalBSONValue(bsonType bsontype.Type, bytes []byte) error {
uid, err := uuid.FromBytes(bytes)
if err != nil {
return err
}
*id = TransactionID(uid)
return nil
}
func NewTransactionID() TransactionID {
return TransactionID(uuid.New())
}
func main() {
id := NewTransactionID()
_, err := bson.Marshal(id)
if err != nil {
log.Fatal(err)
}
}
我在解组步骤中得到 WriteValueBytes can only write while positioned on a Element or Value but is positioned on a TopLevel
。
I'm getting the WriteValueBytes can only write while positioned on a Element or Value but is positioned on a TopLevel in the unmarshal step.
函数bson.Marshal() requires a parameter that can be transformed into a document (i.e. interface{}
). This is why the error message is relating to the position of the value. i.e. you can't have a string on the top level of a document, it needs to be an element of a document. If you need to marshal a single value you should use bson.MarshalValue()代替。
id := NewTransactionID()
vtype, vdata, err := bson.MarshalValue(id)
使用 bson.Marshal()
的示例如下(添加到您的示例中):
type Foo struct {
ID TransactionID
}
func main() {
id := NewTransactionID()
foo, err := bson.Marshal(&Foo{ID:id})
if err != nil {
panic(err)
}
}
尝试为 bson.M
创建自定义 mashler/unmashler 时出现错误WriteValueBytes can only write while positioned on a Element or Value but is positioned on a TopLevel
我有一个名为 TransactionId 的自定义类型,它表示一个 UUID 我想在存储到 monbodb 之前将此值转换为字符串,并在从 mongodb 提取值时将其从字符串转换回。
这是我目前的代码
package main
import (
"github.com/google/uuid"
"github.com/pkg/errors"
"go.mongodb.org/mongo-driver/bson/bsontype"
"go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
"go.mongodb.org/mongo-driver/bson"
"log"
)
// TransactionID is a UUID used to trace a batch of work which is being processed.
type TransactionID uuid.UUID
// String returns the transaction id as a string
func (id TransactionID) String() (result string, err error) {
val, err := uuid.FromBytes(id[:])
if err != nil {
return result, errors.Wrapf(err, "cannot convert transaction ID %s to UUID", string(id[:]))
}
return val.String(), nil
}
func (id TransactionID) MarshalBSONValue() (bsontype.Type, []byte, error) {
idString, err := id.String()
if err != nil {
return bsontype.String, nil, err
}
return bsontype.String, bsoncore.AppendString(nil, idString), nil
}
func (id *TransactionID) UnmarshalBSONValue(bsonType bsontype.Type, bytes []byte) error {
uid, err := uuid.FromBytes(bytes)
if err != nil {
return err
}
*id = TransactionID(uid)
return nil
}
func NewTransactionID() TransactionID {
return TransactionID(uuid.New())
}
func main() {
id := NewTransactionID()
_, err := bson.Marshal(id)
if err != nil {
log.Fatal(err)
}
}
我在解组步骤中得到 WriteValueBytes can only write while positioned on a Element or Value but is positioned on a TopLevel
。
I'm getting the WriteValueBytes can only write while positioned on a Element or Value but is positioned on a TopLevel in the unmarshal step.
函数bson.Marshal() requires a parameter that can be transformed into a document (i.e. interface{}
). This is why the error message is relating to the position of the value. i.e. you can't have a string on the top level of a document, it needs to be an element of a document. If you need to marshal a single value you should use bson.MarshalValue()代替。
id := NewTransactionID()
vtype, vdata, err := bson.MarshalValue(id)
使用 bson.Marshal()
的示例如下(添加到您的示例中):
type Foo struct {
ID TransactionID
}
func main() {
id := NewTransactionID()
foo, err := bson.Marshal(&Foo{ID:id})
if err != nil {
panic(err)
}
}