package meta import ( "io" "github.com/pkg/errors" "github.com/vmihailenco/msgpack/v5" ) type msgpackAssocWriter struct { enc *msgpack.Encoder containers []writeContainer } type writeContainer struct { length int assoc bool } func NewMsgpackAssocWriter(w io.Writer) Writer { return &msgpackAssocWriter{ enc: msgpack.NewEncoder(w), containers: make([]writeContainer, 0, 1), } } func (wr *msgpackAssocWriter) currentContainer() writeContainer { if wr == nil || len(wr.containers) == 0 { return writeContainer{} } return wr.containers[len(wr.containers)-1] } func (wr *msgpackAssocWriter) writeFieldName(field string) error { if !wr.currentContainer().assoc { return nil } return errors.WithStack(wr.enc.EncodeString(field)) } func (wr *msgpackAssocWriter) WriteInt8(v int8, field string) error { if err := wr.writeFieldName(field); err != nil { return err } return errors.WithStack(wr.enc.EncodeInt(int64(v))) } func (wr *msgpackAssocWriter) WriteInt16(v int16, field string) error { if err := wr.writeFieldName(field); err != nil { return err } return errors.WithStack(wr.enc.EncodeInt(int64(v))) } func (wr *msgpackAssocWriter) WriteInt32(v int32, field string) error { if err := wr.writeFieldName(field); err != nil { return err } return errors.WithStack(wr.enc.EncodeInt(int64(v))) } func (wr *msgpackAssocWriter) WriteInt64(v int64, field string) error { if err := wr.writeFieldName(field); err != nil { return err } return errors.WithStack(wr.enc.EncodeInt(v)) } func (wr *msgpackAssocWriter) WriteUint8(v uint8, field string) error { if err := wr.writeFieldName(field); err != nil { return err } return errors.WithStack(wr.enc.EncodeUint(uint64(v))) } func (wr *msgpackAssocWriter) WriteUint16(v uint16, field string) error { if err := wr.writeFieldName(field); err != nil { return err } return errors.WithStack(wr.enc.EncodeUint(uint64(v))) } func (wr *msgpackAssocWriter) WriteUint32(v uint32, field string) error { if err := wr.writeFieldName(field); err != nil { return err } return errors.WithStack(wr.enc.EncodeUint(uint64(v))) } func (wr *msgpackAssocWriter) WriteUint64(v uint64, field string) error { if err := wr.writeFieldName(field); err != nil { return err } return errors.WithStack(wr.enc.EncodeUint(uint64(v))) } func (wr *msgpackAssocWriter) WriteBool(v bool, field string) error { if err := wr.writeFieldName(field); err != nil { return err } return errors.WithStack(wr.enc.EncodeBool(v)) } func (wr *msgpackAssocWriter) WriteFloat32(v float32, field string) error { if err := wr.writeFieldName(field); err != nil { return err } return errors.WithStack(wr.enc.EncodeFloat32(v)) } func (wr *msgpackAssocWriter) WriteFloat64(v float64, field string) error { if err := wr.writeFieldName(field); err != nil { return err } return errors.WithStack(wr.enc.EncodeFloat64(v)) } func (wr *msgpackAssocWriter) WriteString(v string, field string) error { if err := wr.writeFieldName(field); err != nil { return err } return errors.WithStack(wr.enc.EncodeString(v)) } func (wr *msgpackAssocWriter) WriteBytes(v []byte, field string) error { if err := wr.writeFieldName(field); err != nil { return err } return errors.WithStack(wr.enc.EncodeBytes(v)) } func (wr *msgpackAssocWriter) BeginContainer(length int, field string) error { if err := wr.writeFieldName(field); err != nil { return err } if err := wr.enc.EncodeMapLen(length); err != nil { return errors.WithStack(err) } wr.containers = append(wr.containers, writeContainer{ length: length, assoc: true, }) return nil } func (wr *msgpackAssocWriter) EndContainer() error { if len(wr.containers) == 0 { return errors.New("there is no open containers") } wr.containers = wr.containers[:len(wr.containers)-1] return nil } func (wr *msgpackAssocWriter) BeginCollection(length int, field string) error { if err := wr.writeFieldName(field); err != nil { return err } if err := wr.enc.EncodeArrayLen(length); err != nil { return errors.WithStack(err) } wr.containers = append(wr.containers, writeContainer{ length: length, assoc: false, }) return nil } func (wr *msgpackAssocWriter) EndCollection() error { return wr.EndContainer() }