Skip to content

Commit 41aafb6

Browse files
authored
Merge pull request #2 from lightninglabs/1-33-0-hex-display
protojson: add UseHexForBytes option
2 parents ec47fd1 + c8ffcc7 commit 41aafb6

File tree

2 files changed

+38
-3
lines changed

2 files changed

+38
-3
lines changed

encoding/protojson/decode.go

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package protojson
66

77
import (
88
"encoding/base64"
9+
"encoding/hex"
910
"fmt"
1011
"math"
1112
"strconv"
@@ -41,6 +42,10 @@ type UnmarshalOptions struct {
4142
// If DiscardUnknown is set, unknown fields and enum name values are ignored.
4243
DiscardUnknown bool
4344

45+
// If UseHexForBytes is set, bytes fields are un-marshaled as hex
46+
// strings instead of base64.
47+
UseHexForBytes bool
48+
4449
// Resolver is used for looking up types when unmarshaling
4550
// google.protobuf.Any messages or extension fields.
4651
// If nil, this defaults to using protoregistry.GlobalTypes.
@@ -338,8 +343,14 @@ func (d decoder) unmarshalScalar(fd protoreflect.FieldDescriptor) (protoreflect.
338343
}
339344

340345
case protoreflect.BytesKind:
341-
if v, ok := unmarshalBytes(tok); ok {
342-
return v, nil
346+
if d.opts.UseHexForBytes {
347+
if v, ok := unmarshalBytesFromHex(tok); ok {
348+
return v, nil
349+
}
350+
} else {
351+
if v, ok := unmarshalBytes(tok); ok {
352+
return v, nil
353+
}
343354
}
344355

345356
case protoreflect.EnumKind:
@@ -488,6 +499,19 @@ func unmarshalBytes(tok json.Token) (protoreflect.Value, bool) {
488499
return protoreflect.ValueOfBytes(b), true
489500
}
490501

502+
func unmarshalBytesFromHex(tok json.Token) (protoreflect.Value, bool) {
503+
if tok.Kind() != json.String {
504+
return protoreflect.Value{}, false
505+
}
506+
507+
s := tok.ParsedString()
508+
b, err := hex.DecodeString(s)
509+
if err != nil {
510+
return protoreflect.Value{}, false
511+
}
512+
return protoreflect.ValueOfBytes(b), true
513+
}
514+
491515
func unmarshalEnum(tok json.Token, fd protoreflect.FieldDescriptor, discardUnknown bool) (protoreflect.Value, bool) {
492516
switch tok.Kind() {
493517
case json.String:

encoding/protojson/encode.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package protojson
66

77
import (
88
"encoding/base64"
9+
"encoding/hex"
910
"fmt"
1011

1112
"google.golang.org/protobuf/internal/encoding/json"
@@ -100,6 +101,10 @@ type MarshalOptions struct {
100101
// a strict superset of the latter.
101102
EmitDefaultValues bool
102103

104+
// If UseHexForBytes is set, bytes fields are marshaled as hex strings
105+
// instead of base64.
106+
UseHexForBytes bool
107+
103108
// Resolver is used for looking up types when expanding google.protobuf.Any
104109
// messages. If nil, this defaults to using protoregistry.GlobalTypes.
105110
Resolver interface {
@@ -320,7 +325,13 @@ func (e encoder) marshalSingular(val protoreflect.Value, fd protoreflect.FieldDe
320325
e.WriteFloat(val.Float(), 64)
321326

322327
case protoreflect.BytesKind:
323-
e.WriteString(base64.StdEncoding.EncodeToString(val.Bytes()))
328+
var encoded string
329+
if e.opts.UseHexForBytes {
330+
encoded = hex.EncodeToString(val.Bytes())
331+
} else {
332+
encoded = base64.StdEncoding.EncodeToString(val.Bytes())
333+
}
334+
e.WriteString(encoded)
324335

325336
case protoreflect.EnumKind:
326337
if fd.Enum().FullName() == genid.NullValue_enum_fullname {

0 commit comments

Comments
 (0)