diff --git a/encode.go b/encode.go index 6c461884..20ac90be 100644 --- a/encode.go +++ b/encode.go @@ -30,6 +30,7 @@ type Encoder struct { opts []EncodeOption indent int isFlowStyle bool + isJSONStyle bool anchorCallback func(*ast.AnchorNode, interface{}) error anchorPtrToNameMap map[uintptr]string @@ -242,7 +243,7 @@ func (e *Encoder) encodeFloat(v float64) ast.Node { } func (e *Encoder) encodeString(v string, column int) ast.Node { - if token.IsNeedQuoted(v) { + if e.isJSONStyle || token.IsNeedQuoted(v) { v = strconv.Quote(v) } return ast.String(token.New(v, v, e.pos(column))) @@ -368,6 +369,9 @@ func (e *Encoder) isZeroValue(v reflect.Value) bool { func (e *Encoder) encodeTime(v time.Time, column int) ast.Node { value := v.Format(time.RFC3339Nano) + if e.isJSONStyle { + value = strconv.Quote(value) + } return ast.String(token.New(value, value, e.pos(column))) } diff --git a/encode_test.go b/encode_test.go index c1e18b48..093ceab0 100644 --- a/encode_test.go +++ b/encode_test.go @@ -695,6 +695,52 @@ func TestEncoder_Flow(t *testing.T) { } } +func TestEncoder_JSON(t *testing.T) { + var buf bytes.Buffer + enc := yaml.NewEncoder(&buf, yaml.JSON()) + type st struct { + I int8 + S string + F float32 + } + if err := enc.Encode(struct { + I int + U uint + S string + F float64 + Struct *st + Slice []int + Map map[string]interface{} + Time time.Time + }{ + I: -10, + U: 10, + S: "hello", + F: 3.14, + Struct: &st{ + I: 2, + S: "world", + F: 1.23, + }, + Slice: []int{1, 2, 3, 4, 5}, + Map: map[string]interface{}{ + "a": 1, + "b": 1.23, + "c": "json", + }, + Time: time.Time{}, + }); err != nil { + t.Fatalf("%+v", err) + } + expect := ` +{"i": -10, "u": 10, "s": "hello", "f": 3.14, "struct": {"i": 2, "s": "world", "f": 1.23}, "slice": [1, 2, 3, 4, 5], "map": {"a": 1, "b": 1.23, "c": "json"}, "time": "0001-01-01T00:00:00Z"} +` + actual := "\n" + buf.String() + if expect != actual { + t.Fatalf("JSON style marshal error: expect=[%s] actual=[%s]", expect, actual) + } +} + func TestEncoder_MarshalAnchor(t *testing.T) { type Host struct { Hostname string diff --git a/option.go b/option.go index 1b40f3eb..2184b7cf 100644 --- a/option.go +++ b/option.go @@ -104,6 +104,15 @@ func Flow(isFlowStyle bool) EncodeOption { } } +// JSON encode in JSON format +func JSON() EncodeOption { + return func(e *Encoder) error { + e.isJSONStyle = true + e.isFlowStyle = true + return nil + } +} + // MarshalAnchor call back if encoder find an anchor during encoding func MarshalAnchor(callback func(*ast.AnchorNode, interface{}) error) EncodeOption { return func(e *Encoder) error {