Skip to content

Commit

Permalink
Put json.Number encoding behind SetJsonNumber() switch
Browse files Browse the repository at this point in the history
  • Loading branch information
dangra committed Jan 23, 2024
1 parent a578f88 commit c447b2f
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 35 deletions.
1 change: 0 additions & 1 deletion cmd/jsontoml/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ func convert(r io.Reader, w io.Writer) error {
var v interface{}

d := json.NewDecoder(r)
d.UseNumber()
err := d.Decode(&v)
if err != nil {
return err
Expand Down
2 changes: 1 addition & 1 deletion cmd/jsontoml/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func TestConvert(t *testing.T) {
}
}`,
expected: `[mytoml]
a = 42
a = 42.0
`,
},
{
Expand Down
26 changes: 18 additions & 8 deletions marshaler.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ type Encoder struct {
arraysMultiline bool
indentSymbol string
indentTables bool
jsonNumber bool
}

// NewEncoder returns a new Encoder that writes to w.
Expand Down Expand Up @@ -88,6 +89,13 @@ func (enc *Encoder) SetIndentTables(indent bool) *Encoder {
return enc
}

// SetJsonNumber forces the encoder to serialize `json.Number` as a float or integer
// instead of relying on TextMarshaler to emit a string.
func (enc *Encoder) SetJsonNumber(indent bool) *Encoder {
enc.jsonNumber = indent
return enc
}

// Encode writes a TOML representation of v to the stream.
//
// If v cannot be represented to TOML it returns an error.
Expand Down Expand Up @@ -254,14 +262,16 @@ func (enc *Encoder) encode(b []byte, ctx encoderCtx, v reflect.Value) ([]byte, e
case LocalDateTime:
return append(b, x.String()...), nil
case json.Number:
if x == "" { /// Useful zero value.
return append(b, "0"...), nil
} else if v, err := x.Int64(); err == nil {
return enc.encode(b, ctx, reflect.ValueOf(v))
} else if f, err := x.Float64(); err == nil {
return enc.encode(b, ctx, reflect.ValueOf(f))
} else {
return nil, fmt.Errorf("toml: unable to convert %q to int64 or float64", x)
if enc.jsonNumber {
if x == "" { /// Useful zero value.
return append(b, "0"...), nil
} else if v, err := x.Int64(); err == nil {
return enc.encode(b, ctx, reflect.ValueOf(v))
} else if f, err := x.Float64(); err == nil {
return enc.encode(b, ctx, reflect.ValueOf(f))
} else {
return nil, fmt.Errorf("toml: unable to convert %q to int64 or float64", x)
}
}
}

Expand Down
48 changes: 23 additions & 25 deletions marshaler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -679,31 +679,6 @@ I = 42
J = 42
K = 42
L = 2.2
`,
},
{
desc: "json numbers",
v: struct {
A json.Number
B json.Number
C json.Number
D json.Number
E json.Number
F json.Number
}{
A: "1.1",
B: "42e-3",
C: "42",
D: "0",
E: "0.0",
F: "",
},
expected: `A = 1.1
B = 0.042
C = 42
D = 0
E = 0.0
F = 0
`,
},
{
Expand Down Expand Up @@ -973,6 +948,29 @@ func TestEncoderSetIndentSymbol(t *testing.T) {
assert.Equal(t, expected, w.String())
}

func TestEncoderSetJsonNumber(t *testing.T) {
var w strings.Builder
enc := toml.NewEncoder(&w)
enc.SetJsonNumber(true)
err := enc.Encode(map[string]interface{}{
"A": json.Number("1.1"),
"B": json.Number("42e-3"),
"C": json.Number("42"),
"D": json.Number("0"),
"E": json.Number("0.0"),
"F": json.Number(""),
})
require.NoError(t, err)
expected := `A = 1.1
B = 0.042
C = 42
D = 0
E = 0.0
F = 0
`
assert.Equal(t, expected, w.String())
}

func TestEncoderOmitempty(t *testing.T) {
type doc struct {
String string `toml:",omitempty,multiline"`
Expand Down

0 comments on commit c447b2f

Please sign in to comment.