forked from TrueCloudLab/frostfs-api-go
Add stable marshaler for enums
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
This commit is contained in:
parent
f8482381fd
commit
a7a8fc33bb
4 changed files with 163 additions and 17 deletions
|
@ -120,6 +120,14 @@ func Int32Size(field int, v int32) int {
|
|||
return UInt64Size(field, uint64(v))
|
||||
}
|
||||
|
||||
func EnumMarshal(field int, buf []byte, v int32) (int, error) {
|
||||
return UInt64Marshal(field, buf, uint64(v))
|
||||
}
|
||||
|
||||
func EnumSize(field int, v int32) int {
|
||||
return UInt64Size(field, uint64(v))
|
||||
}
|
||||
|
||||
// varUIntSize returns length of varint byte sequence for uint64 value 'x'.
|
||||
func VarUIntSize(x uint64) int {
|
||||
return (bits.Len64(x|1) + 6) / 7
|
||||
|
|
|
@ -10,6 +10,8 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
type SomeEnum int32
|
||||
|
||||
type stablePrimitives struct {
|
||||
FieldA []byte
|
||||
FieldB string
|
||||
|
@ -18,8 +20,15 @@ type stablePrimitives struct {
|
|||
FieldE uint32
|
||||
FieldF int64
|
||||
FieldG uint64
|
||||
FieldH SomeEnum
|
||||
}
|
||||
|
||||
const (
|
||||
ENUM_UNKNOWN SomeEnum = 0
|
||||
ENUM_POSITIVE = 1
|
||||
ENUM_NEGATIVE = -1
|
||||
)
|
||||
|
||||
func (s *stablePrimitives) stableMarshal(buf []byte, wrongField bool) ([]byte, error) {
|
||||
if s == nil {
|
||||
return []byte{}, nil
|
||||
|
@ -103,6 +112,16 @@ func (s *stablePrimitives) stableMarshal(buf []byte, wrongField bool) ([]byte, e
|
|||
}
|
||||
i += offset
|
||||
|
||||
fieldNum = 300
|
||||
if wrongField {
|
||||
fieldNum++
|
||||
}
|
||||
offset, err = proto.EnumMarshal(fieldNum, buf, int32(s.FieldH))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "can't marshal field g")
|
||||
}
|
||||
i += offset
|
||||
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
|
@ -113,7 +132,8 @@ func (s *stablePrimitives) stableSize() int {
|
|||
proto.Int32Size(201, s.FieldD) +
|
||||
proto.UInt32Size(202, s.FieldE) +
|
||||
proto.Int64Size(203, s.FieldF) +
|
||||
proto.UInt64Size(204, s.FieldG)
|
||||
proto.UInt64Size(204, s.FieldG) +
|
||||
proto.EnumSize(300, int32(s.FieldH))
|
||||
}
|
||||
|
||||
func TestBytesMarshal(t *testing.T) {
|
||||
|
@ -209,6 +229,14 @@ func TestUInt64Marshal(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestEnumMarshal(t *testing.T) {
|
||||
testEnumMarshal(t, ENUM_UNKNOWN, false)
|
||||
testEnumMarshal(t, ENUM_POSITIVE, false)
|
||||
testEnumMarshal(t, ENUM_POSITIVE, true)
|
||||
testEnumMarshal(t, ENUM_NEGATIVE, false)
|
||||
testEnumMarshal(t, ENUM_NEGATIVE, true)
|
||||
}
|
||||
|
||||
func testBytesMarshal(t *testing.T, data []byte, wrongField bool) {
|
||||
var (
|
||||
wire []byte
|
||||
|
@ -398,3 +426,36 @@ func testUInt64Marshal(t *testing.T, n uint64, wrongField bool) {
|
|||
require.EqualValues(t, 0, result.FieldG)
|
||||
}
|
||||
}
|
||||
|
||||
func testEnumMarshal(t *testing.T, e SomeEnum, wrongField bool) {
|
||||
var (
|
||||
wire []byte
|
||||
err error
|
||||
|
||||
custom = stablePrimitives{FieldH: e}
|
||||
transport = test.Primitives{FieldH: test.Primitives_SomeEnum(e)}
|
||||
)
|
||||
|
||||
wire, err = custom.stableMarshal(nil, wrongField)
|
||||
require.NoError(t, err)
|
||||
|
||||
wireGen, err := transport.Marshal()
|
||||
require.NoError(t, err)
|
||||
|
||||
if !wrongField {
|
||||
// we can check equality because single field cannot be unstable marshalled
|
||||
require.Equal(t, wireGen, wire)
|
||||
} else {
|
||||
require.NotEqual(t, wireGen, wire)
|
||||
}
|
||||
|
||||
result := new(test.Primitives)
|
||||
err = result.Unmarshal(wire)
|
||||
require.NoError(t, err)
|
||||
|
||||
if !wrongField {
|
||||
require.EqualValues(t, custom.FieldH, result.FieldH)
|
||||
} else {
|
||||
require.EqualValues(t, 0, result.FieldH)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,17 +22,46 @@ var _ = math.Inf
|
|||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
type Primitives_SomeEnum int32
|
||||
|
||||
const (
|
||||
Primitives_UNKNOWN Primitives_SomeEnum = 0
|
||||
Primitives_POSITIVE Primitives_SomeEnum = 1
|
||||
Primitives_NEGATIVE Primitives_SomeEnum = -1
|
||||
)
|
||||
|
||||
var Primitives_SomeEnum_name = map[int32]string{
|
||||
0: "UNKNOWN",
|
||||
1: "POSITIVE",
|
||||
-1: "NEGATIVE",
|
||||
}
|
||||
|
||||
var Primitives_SomeEnum_value = map[string]int32{
|
||||
"UNKNOWN": 0,
|
||||
"POSITIVE": 1,
|
||||
"NEGATIVE": -1,
|
||||
}
|
||||
|
||||
func (x Primitives_SomeEnum) String() string {
|
||||
return proto.EnumName(Primitives_SomeEnum_name, int32(x))
|
||||
}
|
||||
|
||||
func (Primitives_SomeEnum) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_998ad0e1a3de8558, []int{0, 0}
|
||||
}
|
||||
|
||||
type Primitives struct {
|
||||
FieldA []byte `protobuf:"bytes,1,opt,name=field_a,json=fieldA,proto3" json:"field_a,omitempty"`
|
||||
FieldB string `protobuf:"bytes,2,opt,name=field_b,json=fieldB,proto3" json:"field_b,omitempty"`
|
||||
FieldC bool `protobuf:"varint,200,opt,name=field_c,json=fieldC,proto3" json:"field_c,omitempty"`
|
||||
FieldD int32 `protobuf:"varint,201,opt,name=field_d,json=fieldD,proto3" json:"field_d,omitempty"`
|
||||
FieldE uint32 `protobuf:"varint,202,opt,name=field_e,json=fieldE,proto3" json:"field_e,omitempty"`
|
||||
FieldF int64 `protobuf:"varint,203,opt,name=field_f,json=fieldF,proto3" json:"field_f,omitempty"`
|
||||
FieldG uint64 `protobuf:"varint,204,opt,name=field_g,json=fieldG,proto3" json:"field_g,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
FieldA []byte `protobuf:"bytes,1,opt,name=field_a,json=fieldA,proto3" json:"field_a,omitempty"`
|
||||
FieldB string `protobuf:"bytes,2,opt,name=field_b,json=fieldB,proto3" json:"field_b,omitempty"`
|
||||
FieldC bool `protobuf:"varint,200,opt,name=field_c,json=fieldC,proto3" json:"field_c,omitempty"`
|
||||
FieldD int32 `protobuf:"varint,201,opt,name=field_d,json=fieldD,proto3" json:"field_d,omitempty"`
|
||||
FieldE uint32 `protobuf:"varint,202,opt,name=field_e,json=fieldE,proto3" json:"field_e,omitempty"`
|
||||
FieldF int64 `protobuf:"varint,203,opt,name=field_f,json=fieldF,proto3" json:"field_f,omitempty"`
|
||||
FieldG uint64 `protobuf:"varint,204,opt,name=field_g,json=fieldG,proto3" json:"field_g,omitempty"`
|
||||
FieldH Primitives_SomeEnum `protobuf:"varint,300,opt,name=field_h,json=fieldH,proto3,enum=test.Primitives_SomeEnum" json:"field_h,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Primitives) Reset() { *m = Primitives{} }
|
||||
|
@ -117,26 +146,38 @@ func (m *Primitives) GetFieldG() uint64 {
|
|||
return 0
|
||||
}
|
||||
|
||||
func (m *Primitives) GetFieldH() Primitives_SomeEnum {
|
||||
if m != nil {
|
||||
return m.FieldH
|
||||
}
|
||||
return Primitives_UNKNOWN
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterEnum("test.Primitives_SomeEnum", Primitives_SomeEnum_name, Primitives_SomeEnum_value)
|
||||
proto.RegisterType((*Primitives)(nil), "test.Primitives")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("util/proto/test/test.proto", fileDescriptor_998ad0e1a3de8558) }
|
||||
|
||||
var fileDescriptor_998ad0e1a3de8558 = []byte{
|
||||
// 178 bytes of a gzipped FileDescriptorProto
|
||||
// 254 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x2a, 0x2d, 0xc9, 0xcc,
|
||||
0xd1, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0xd7, 0x2f, 0x49, 0x2d, 0x2e, 0x01, 0x13, 0x7a, 0x60, 0xbe,
|
||||
0x10, 0x0b, 0x88, 0xad, 0x74, 0x80, 0x91, 0x8b, 0x2b, 0xa0, 0x28, 0x33, 0x37, 0xb3, 0x24, 0xb3,
|
||||
0x10, 0x0b, 0x88, 0xad, 0xb4, 0x99, 0x89, 0x8b, 0x2b, 0xa0, 0x28, 0x33, 0x37, 0xb3, 0x24, 0xb3,
|
||||
0x2c, 0xb5, 0x58, 0x48, 0x9c, 0x8b, 0x3d, 0x2d, 0x33, 0x35, 0x27, 0x25, 0x3e, 0x51, 0x82, 0x51,
|
||||
0x81, 0x51, 0x83, 0x27, 0x88, 0x0d, 0xcc, 0x75, 0x44, 0x48, 0x24, 0x49, 0x30, 0x29, 0x30, 0x6a,
|
||||
0x70, 0x42, 0x25, 0x9c, 0x84, 0x24, 0x60, 0x12, 0xc9, 0x12, 0x27, 0x40, 0x5a, 0x38, 0xa0, 0x32,
|
||||
0xce, 0x08, 0x99, 0x14, 0x89, 0x93, 0x20, 0x19, 0x56, 0xa8, 0x8c, 0x0b, 0x42, 0x26, 0x55, 0xe2,
|
||||
0x14, 0x48, 0x86, 0x17, 0x2a, 0xe3, 0x8a, 0x90, 0x49, 0x93, 0x38, 0x0d, 0x92, 0x61, 0x86, 0xca,
|
||||
0xb8, 0x21, 0x64, 0xd2, 0x25, 0xce, 0x80, 0x64, 0x58, 0xa0, 0x32, 0xee, 0x4e, 0x02, 0x27, 0x1e,
|
||||
0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c, 0xe3, 0x8c, 0xc7, 0x72, 0x0c, 0x49,
|
||||
0x6c, 0x60, 0x1f, 0x1a, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0xcc, 0xee, 0x55, 0x82, 0xff, 0x00,
|
||||
0x00, 0x00,
|
||||
0xb8, 0x21, 0x64, 0xd2, 0x25, 0xce, 0x80, 0x64, 0x58, 0xa0, 0x32, 0xee, 0x42, 0xc6, 0x30, 0x99,
|
||||
0x0c, 0x89, 0x35, 0x20, 0xb7, 0xf1, 0x19, 0x49, 0xea, 0x81, 0xfd, 0x89, 0xf0, 0x97, 0x5e, 0x70,
|
||||
0x7e, 0x6e, 0xaa, 0x6b, 0x5e, 0x69, 0x2e, 0x54, 0x93, 0x87, 0x92, 0x0d, 0x17, 0x07, 0x4c, 0x4c,
|
||||
0x88, 0x9b, 0x8b, 0x3d, 0xd4, 0xcf, 0xdb, 0xcf, 0x3f, 0xdc, 0x4f, 0x80, 0x41, 0x88, 0x87, 0x8b,
|
||||
0x23, 0xc0, 0x3f, 0xd8, 0x33, 0xc4, 0x33, 0xcc, 0x55, 0x80, 0x51, 0x48, 0x94, 0x8b, 0xc3, 0xcf,
|
||||
0xd5, 0xdd, 0x11, 0xcc, 0xfb, 0x0f, 0x03, 0x8c, 0x4e, 0x02, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78,
|
||||
0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c, 0xe3, 0x8c, 0xc7, 0x72, 0x0c, 0x49, 0x6c, 0xe0, 0x40, 0x35,
|
||||
0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0x10, 0xfa, 0xa0, 0xf4, 0x72, 0x01, 0x00, 0x00,
|
||||
}
|
||||
|
||||
func (m *Primitives) Marshal() (dAtA []byte, err error) {
|
||||
|
@ -163,6 +204,13 @@ func (m *Primitives) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
|||
i -= len(m.XXX_unrecognized)
|
||||
copy(dAtA[i:], m.XXX_unrecognized)
|
||||
}
|
||||
if m.FieldH != 0 {
|
||||
i = encodeVarintTest(dAtA, i, uint64(m.FieldH))
|
||||
i--
|
||||
dAtA[i] = 0x12
|
||||
i--
|
||||
dAtA[i] = 0xe0
|
||||
}
|
||||
if m.FieldG != 0 {
|
||||
i = encodeVarintTest(dAtA, i, uint64(m.FieldG))
|
||||
i--
|
||||
|
@ -260,6 +308,9 @@ func (m *Primitives) Size() (n int) {
|
|||
if m.FieldG != 0 {
|
||||
n += 2 + sovTest(uint64(m.FieldG))
|
||||
}
|
||||
if m.FieldH != 0 {
|
||||
n += 2 + sovTest(uint64(m.FieldH))
|
||||
}
|
||||
if m.XXX_unrecognized != nil {
|
||||
n += len(m.XXX_unrecognized)
|
||||
}
|
||||
|
@ -463,6 +514,25 @@ func (m *Primitives) Unmarshal(dAtA []byte) error {
|
|||
break
|
||||
}
|
||||
}
|
||||
case 300:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field FieldH", wireType)
|
||||
}
|
||||
m.FieldH = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowTest
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.FieldH |= Primitives_SomeEnum(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipTest(dAtA[iNdEx:])
|
||||
|
|
|
@ -10,4 +10,11 @@ message Primitives {
|
|||
uint32 field_e = 202;
|
||||
int64 field_f = 203;
|
||||
uint64 field_g = 204;
|
||||
|
||||
enum SomeEnum {
|
||||
UNKNOWN = 0;
|
||||
POSITIVE = 1;
|
||||
NEGATIVE = -1;
|
||||
}
|
||||
SomeEnum field_h = 300;
|
||||
}
|
Loading…
Reference in a new issue