Skip to content

Commit 18fc58a

Browse files
committed
feat: support automatic camel case field key
Add camel case encoding option Add camel case key conversion Add camel case test
1 parent 23bd66f commit 18fc58a

File tree

4 files changed

+47
-2
lines changed

4 files changed

+47
-2
lines changed

encode_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2388,3 +2388,29 @@ func TestIssue324(t *testing.T) {
23882388
t.Fatalf("failed to encode. expected %q but got %q", expected, got)
23892389
}
23902390
}
2391+
2392+
func TestIssue271(t *testing.T) {
2393+
type T struct {
2394+
FieldA bool
2395+
}
2396+
2397+
type T2 struct {
2398+
FieldA bool `json:"fieldA"`
2399+
}
2400+
2401+
v := T{FieldA: true}
2402+
got, err := json.MarshalWithOption(v, json.EnableCamelCase())
2403+
if err != nil {
2404+
t.Fatal(err)
2405+
}
2406+
2407+
v2 := T2{FieldA: true}
2408+
expected, err := json.Marshal(v2)
2409+
if err != nil {
2410+
t.Fatal(err)
2411+
}
2412+
2413+
if !bytes.Equal(expected, got) {
2414+
t.Fatalf("failed to encode. expected %q but got %q", expected, got)
2415+
}
2416+
}

internal/encoder/option.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
"io"
66
)
77

8-
type OptionFlag uint8
8+
type OptionFlag uint16
99

1010
const (
1111
HTMLEscapeOption OptionFlag = 1 << iota
@@ -16,6 +16,7 @@ const (
1616
ContextOption
1717
NormalizeUTF8Option
1818
FieldQueryOption
19+
CamelCaseOption
1920
)
2021

2122
type Option struct {

internal/encoder/vm/util.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package vm
33
import (
44
"encoding/json"
55
"fmt"
6+
"unicode"
67
"unsafe"
78

89
"github.com/goccy/go-json/internal/encoder"
@@ -184,7 +185,17 @@ func appendStructHead(_ *encoder.RuntimeContext, b []byte) []byte {
184185
return append(b, '{')
185186
}
186187

187-
func appendStructKey(_ *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
188+
func appendStructKey(e *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
189+
if e.Option.Flag&encoder.CamelCaseOption > 0 {
190+
key := []rune(code.Key)
191+
for i := range key {
192+
if unicode.IsLetter(key[i]) {
193+
key[i] = unicode.ToLower(key[i])
194+
break
195+
}
196+
}
197+
return append(b, string(key)...)
198+
}
188199
return append(b, code.Key...)
189200
}
190201

option.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ func DisableHTMLEscape() EncodeOptionFunc {
2424
}
2525
}
2626

27+
// EnableCamelCase enables the use of camel case keys when encoding struct and the key is not specified in tags.
28+
func EnableCamelCase() EncodeOptionFunc {
29+
return func(opt *EncodeOption) {
30+
opt.Flag |= encoder.CamelCaseOption
31+
}
32+
}
33+
2734
// DisableNormalizeUTF8
2835
// By default, when encoding string, UTF8 characters in the range of 0x80 - 0xFF are processed by applying \ufffd for invalid code and escaping for \u2028 and \u2029.
2936
// This option disables this behaviour. You can expect faster speeds by applying this option, but be careful.

0 commit comments

Comments
 (0)