Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ generate: build
bin/easyjson -build_tags=use_easyjson -disable_members_unescape ./benchmark/data.go
bin/easyjson -disallow_unknown_fields ./tests/disallow_unknown.go
bin/easyjson -disable_members_unescape ./tests/members_unescaped.go
bin/easyjson -float_format='f' ./tests/float_format.go

test: generate
go test \
Expand Down
36 changes: 19 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,35 +53,37 @@ for more information and features.
```txt
Usage of easyjson:
-all
generate marshaler/unmarshalers for all structs in a file
generate marshaler/unmarshalers for all structs in a file
-build_tags string
build tags to add to generated file
-gen_build_flags string
build flags when running the generator while bootstrapping
-byte
use simple bytes instead of Base64Bytes for slice of bytes
-disable_members_unescape
don't perform unescaping of member names to improve performance
-disallow_unknown_fields
return error if any unknown field in json appeared
-float_format string
float format to be used in json writer
-gen_build_flags string
build flags when running the generator while bootstrapping
-leave_temps
do not delete temporary files
do not delete temporary files
-lower_camel_case
use lowerCamelCase names instead of CamelCase by default
-no_std_marshalers
don't generate MarshalJSON/UnmarshalJSON funcs
don't generate MarshalJSON/UnmarshalJSON funcs
-noformat
do not run 'gofmt -w' on output file
do not run 'gofmt -w' on output file
-omit_empty
omit empty fields by default
omit empty fields by default
-output_filename string
specify the filename of the output
specify the filename of the output
-pkg
process the whole package instead of just the given file
process the whole package instead of just the given file
-snake_case
use snake_case names instead of CamelCase by default
-lower_camel_case
use lowerCamelCase instead of CamelCase by default
use snake_case names instead of CamelCase by default
-stubs
only generate stubs for marshaler/unmarshaler funcs
-disallow_unknown_fields
return error if some unknown field in json appeared
-disable_members_unescape
disable unescaping of \uXXXX string sequences in member names
only generate stubs for marshaler/unmarshaler funcs
```

Using `-all` will generate marshalers/unmarshalers for all Go structs in the
Expand Down
4 changes: 4 additions & 0 deletions bootstrap/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type Generator struct {
OutName string
BuildTags string
GenBuildFlags string
FloatFmt string

StubsOnly bool
LeaveTemps bool
Expand Down Expand Up @@ -116,6 +117,9 @@ func (g *Generator) writeMain() (path string, err error) {
if g.BuildTags != "" {
fmt.Fprintf(f, " g.SetBuildTags(%q)\n", g.BuildTags)
}
if g.FloatFmt != "" {
fmt.Fprintf(f, " g.SetFloatFmt(%q)\n", g.FloatFmt)
}
if g.SnakeCase {
fmt.Fprintln(f, " g.UseSnakeCase()")
}
Expand Down
7 changes: 7 additions & 0 deletions easyjson/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (

var buildTags = flag.String("build_tags", "", "build tags to add to generated file")
var genBuildFlags = flag.String("gen_build_flags", "", "build flags when running the generator while bootstrapping")
var floatFmt = flag.String("float_format", "", "float format to be used in json writer")
var snakeCase = flag.Bool("snake_case", false, "use snake_case names instead of CamelCase by default")
var lowerCamelCase = flag.Bool("lower_camel_case", false, "use lowerCamelCase names instead of CamelCase by default")
var noStdMarshalers = flag.Bool("no_std_marshalers", false, "don't generate MarshalJSON/UnmarshalJSON funcs")
Expand Down Expand Up @@ -68,6 +69,11 @@ func generate(fname string) (err error) {
trimmedGenBuildFlags = strings.TrimSpace(*genBuildFlags)
}

var trimmedFloatFmt string
if *floatFmt != "" {
trimmedFloatFmt = strings.TrimSpace(*floatFmt)
}

g := bootstrap.Generator{
BuildTags: trimmedBuildTags,
GenBuildFlags: trimmedGenBuildFlags,
Expand All @@ -85,6 +91,7 @@ func generate(fname string) (err error) {
StubsOnly: *stubs,
NoFormat: *noformat,
SimpleBytes: *simpleBytes,
FloatFmt: trimmedFloatFmt,
}

if err := g.Run(); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion gen/encoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ func (g *Generator) genStructMarshaler(t reflect.Type) error {
if !g.noStdMarshalers {
fmt.Fprintln(g.out, "// MarshalJSON supports json.Marshaler interface")
fmt.Fprintln(g.out, "func (v "+typ+") MarshalJSON() ([]byte, error) {")
fmt.Fprintln(g.out, " w := jwriter.Writer{}")
fmt.Fprintf(g.out, " w := jwriter.Writer{FloatFmt:\"%s\"}\n", g.floatFmt)
fmt.Fprintln(g.out, " "+fname+"(&w, v)")
fmt.Fprintln(g.out, " return w.Buffer.BuildBytes(), w.Error")
fmt.Fprintln(g.out, "}")
Expand Down
6 changes: 6 additions & 0 deletions gen/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type Generator struct {
fieldNamer FieldNamer
simpleBytes bool
skipMemberNameUnescaping bool
floatFmt string
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not byte?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd made it string to keep it consistent with the incoming flag which would be string. Also, in case we use byte and pass it as empty, the generator sets it as:

w := jwriter.Writer{FloatFmt: "0"}

I could try figuring this out further if byte seems more relevant as the type of floatFmt, but I guess it should be ok to keep it as string?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can check what value is correct on code generation stage and pass default value if cmd line parameter not passed

Copy link
Author

@rhnvrm rhnvrm Apr 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So currently, since the flag package does not have support for byte/rune flags, it is a bit difficult to do this. I guess it might be okay to keep it as is (?), since the internal method converts the string to byte and sets the default value as well.


// package path to local alias map for tracking imports
imports map[string]string
Expand Down Expand Up @@ -133,6 +134,11 @@ func (g *Generator) SimpleBytes() {
g.simpleBytes = true
}

// SetFloatFmt sets the format for formatting float numbers using strconv.
func (g *Generator) SetFloatFmt(fmt string) {
g.floatFmt = fmt
}

// addTypes requests to generate encoding/decoding funcs for the given type.
func (g *Generator) addType(t reflect.Type) {
if g.typesSeen[t] {
Expand Down
17 changes: 13 additions & 4 deletions jwriter/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type Writer struct {
Error error
Buffer buffer.Buffer
NoEscapeHTML bool
FloatFmt string
}

// Size returns the size of the data that was written out.
Expand Down Expand Up @@ -237,28 +238,36 @@ func (w *Writer) Int64Str(n int64) {

func (w *Writer) Float32(n float32) {
w.Buffer.EnsureSpace(20)
w.Buffer.Buf = strconv.AppendFloat(w.Buffer.Buf, float64(n), 'g', -1, 32)
w.Buffer.Buf = strconv.AppendFloat(w.Buffer.Buf, float64(n), w.floatFmt(), -1, 32)
}

func (w *Writer) Float32Str(n float32) {
w.Buffer.EnsureSpace(20)
w.Buffer.Buf = append(w.Buffer.Buf, '"')
w.Buffer.Buf = strconv.AppendFloat(w.Buffer.Buf, float64(n), 'g', -1, 32)
w.Buffer.Buf = strconv.AppendFloat(w.Buffer.Buf, float64(n), w.floatFmt(), -1, 32)
w.Buffer.Buf = append(w.Buffer.Buf, '"')
}

func (w *Writer) Float64(n float64) {
w.Buffer.EnsureSpace(20)
w.Buffer.Buf = strconv.AppendFloat(w.Buffer.Buf, n, 'g', -1, 64)
w.Buffer.Buf = strconv.AppendFloat(w.Buffer.Buf, n, w.floatFmt(), -1, 64)
}

func (w *Writer) Float64Str(n float64) {
w.Buffer.EnsureSpace(20)
w.Buffer.Buf = append(w.Buffer.Buf, '"')
w.Buffer.Buf = strconv.AppendFloat(w.Buffer.Buf, float64(n), 'g', -1, 64)
w.Buffer.Buf = strconv.AppendFloat(w.Buffer.Buf, float64(n), w.floatFmt(), -1, 64)
w.Buffer.Buf = append(w.Buffer.Buf, '"')
}

func (w *Writer) floatFmt() byte {
if len(w.FloatFmt) < 1 {
return 'g'
}

return w.FloatFmt[0]
}

func (w *Writer) Bool(v bool) {
w.Buffer.EnsureSpace(5)
if v {
Expand Down
3 changes: 2 additions & 1 deletion tests/basic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ var testCases = []struct {
{&structsValue, structsString},
{&omitEmptyValue, omitEmptyString},
{&snakeStructValue, snakeStructString},
{&floatFmtStruct, floatFmtString},
{&omitEmptyDefaultValue, omitEmptyDefaultString},
{&optsValue, optsString},
{&rawValue, rawString},
Expand Down Expand Up @@ -244,7 +245,7 @@ func TestNestedMarshaler(t *testing.T) {
t.Errorf("Can't marshal NestedMarshaler: %s", err)
}

s2 := NestedMarshaler {
s2 := NestedMarshaler{
Value: &StructWithMarshaler{},
}

Expand Down
13 changes: 13 additions & 0 deletions tests/float_format.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package tests

//easyjson:json
type FloatFmtStruct struct {
A float64 `json:"a"`
B float64 `json:"b"`
}

var floatFmtStruct = FloatFmtStruct{
A: 100000000,
B: 1000,
}
var floatFmtString = `{"a":100000000,"b":1000}`