feat(x/tx): add indent option to encoder (#17600)

This commit is contained in:
Julien Robert 2023-09-11 19:03:48 +02:00 committed by GitHub
parent 152ec9293b
commit 91fad07bb7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 98 additions and 2 deletions

View File

@ -31,6 +31,13 @@ Ref: https://keepachangelog.com/en/1.0.0/
## [Unreleased]
## v0.10.0
### Features
* [#17600](https://github.com/cosmos/cosmos-sdk/pull/17600) Add encoder `DefineScalarEncoding` method for defining custom scalar encodings.
* [#17600](https://github.com/cosmos/cosmos-sdk/pull/17600) Add indent option to encoder.
## v0.9.1
### Improvements

View File

@ -23,7 +23,10 @@ type FieldEncoder func(*Encoder, protoreflect.Value, io.Writer) error
// EncoderOptions are options for creating a new Encoder.
type EncoderOptions struct {
// DonotSortFields when set turns off sorting of field names.
// Indent can only be composed of space or tab characters.
// It defines the indentation used for each level of indentation.
Indent string
// DoNotSortFields when set turns off sorting of field names.
DoNotSortFields bool
// TypeResolver is used to resolve protobuf message types by TypeURL when marshaling any packed messages.
TypeResolver signing.TypeResolver
@ -40,6 +43,7 @@ type Encoder struct {
fileResolver signing.ProtoFileResolver
typeResolver protoregistry.MessageTypeResolver
doNotSortFields bool
indent string
}
// NewEncoder returns a new Encoder capable of serializing protobuf messages to JSON using the Amino JSON encoding
@ -67,6 +71,7 @@ func NewEncoder(options EncoderOptions) Encoder {
fileResolver: options.FileResolver,
typeResolver: options.TypeResolver,
doNotSortFields: options.DoNotSortFields,
indent: options.Indent,
}
return enc
}
@ -109,10 +114,36 @@ func (enc Encoder) DefineFieldEncoding(name string, encoder FieldEncoder) Encode
return enc
}
// DefineScalarEncoding defines a custom encoding for a protobuf scalar field. The `name` field must match a usage of
// an (cosmos_proto.scalar) option in the protobuf message as in the following example. This encoding will be used
// instead of the default encoding for all usages of the tagged field.
//
// message Balance {
// string address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// ...
// }
func (enc Encoder) DefineScalarEncoding(name string, encoder FieldEncoder) Encoder {
if enc.scalarEncoders == nil {
enc.scalarEncoders = map[string]FieldEncoder{}
}
enc.scalarEncoders[name] = encoder
return enc
}
// Marshal serializes a protobuf message to JSON.
func (enc Encoder) Marshal(message proto.Message) ([]byte, error) {
buf := &bytes.Buffer{}
err := enc.beginMarshal(message.ProtoReflect(), buf)
if enc.indent != "" {
indentBuf := &bytes.Buffer{}
if err := json.Indent(indentBuf, buf.Bytes(), "", enc.indent); err != nil {
return nil, err
}
return indentBuf.Bytes(), err
}
return buf.Bytes(), err
}

View File

@ -174,6 +174,64 @@ func TestDynamicPb(t *testing.T) {
require.NoError(t, err)
dynamicBz, err := encoder.Marshal(dynamicMsg)
require.NoError(t, err)
fmt.Printf("dynamicBz: %s\n", string(dynamicBz))
require.Equal(t, string(bz), string(dynamicBz))
}
func TestIndent(t *testing.T) {
encoder := aminojson.NewEncoder(aminojson.EncoderOptions{Indent: " "})
msg := &testpb.ABitOfEverything{
Message: &testpb.NestedMessage{
Foo: "test",
Bar: 0, // this is the default value and should be omitted from output
},
Enum: testpb.AnEnum_ONE,
Repeated: []int32{3, -7, 2, 6, 4},
Str: `abcxyz"foo"def`,
Bool: true,
Bytes: []byte{0, 1, 2, 3},
I32: -15,
F32: 1001,
U32: 1200,
Si32: -376,
Sf32: -1000,
I64: 14578294827584932,
F64: 9572348124213523654,
U64: 4759492485,
Si64: -59268425823934,
Sf64: -659101379604211154,
}
bz, err := encoder.Marshal(msg)
require.NoError(t, err)
fmt.Println(string(bz))
require.Equal(t, `{
"type": "ABitOfEverything",
"value": {
"bool": true,
"bytes": "AAECAw==",
"enum": 1,
"f32": 1001,
"f64": "9572348124213523654",
"i32": -15,
"i64": "14578294827584932",
"message": {
"foo": "test"
},
"repeated": [
3,
-7,
2,
6,
4
],
"sf32": -1000,
"sf64": "-659101379604211154",
"si32": -376,
"si64": "-59268425823934",
"str": "abcxyz\"foo\"def",
"u32": 1200,
"u64": "4759492485"
}
}`, string(bz))
}