diff --git a/encode.go b/encode.go index c9527c0..4bd899f 100644 --- a/encode.go +++ b/encode.go @@ -3,6 +3,7 @@ package json import ( "context" "io" + "os" "unsafe" "github.com/goccy/go-json/internal/encoder" @@ -62,6 +63,7 @@ func (e *Encoder) encodeWithOption(ctx *encoder.RuntimeContext, v interface{}, o ctx.Option.Flag |= encoder.HTMLEscapeOption } ctx.Option.Flag |= encoder.NormalizeUTF8Option + ctx.Option.DebugOut = os.Stdout for _, optFunc := range optFuncs { optFunc(ctx.Option) } diff --git a/encode_test.go b/encode_test.go index 469b655..92f4304 100644 --- a/encode_test.go +++ b/encode_test.go @@ -477,7 +477,8 @@ func TestDebugMode(t *testing.T) { t.Fatal("expected error") } }() - json.MarshalWithOption(mustErrTypeForDebug{}, json.Debug()) + var buf bytes.Buffer + json.MarshalWithOption(mustErrTypeForDebug{}, json.Debug(), json.DebugWith(&buf)) } func TestIssue116(t *testing.T) { diff --git a/internal/encoder/option.go b/internal/encoder/option.go index dcec8f2..82d5ce3 100644 --- a/internal/encoder/option.go +++ b/internal/encoder/option.go @@ -1,6 +1,9 @@ package encoder -import "context" +import ( + "context" + "io" +) type OptionFlag uint8 @@ -19,6 +22,7 @@ type Option struct { Flag OptionFlag ColorScheme *ColorScheme Context context.Context + DebugOut io.Writer } type EncodeFormat struct { diff --git a/internal/encoder/vm/debug_vm.go b/internal/encoder/vm/debug_vm.go index 05509fe..fbbc0de 100644 --- a/internal/encoder/vm/debug_vm.go +++ b/internal/encoder/vm/debug_vm.go @@ -16,16 +16,17 @@ func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) } if err := recover(); err != nil { - fmt.Println("=============[DEBUG]===============") - fmt.Println("* [TYPE]") - fmt.Println(codeSet.Type) - fmt.Printf("\n") - fmt.Println("* [ALL OPCODE]") - fmt.Println(code.Dump()) - fmt.Printf("\n") - fmt.Println("* [CONTEXT]") - fmt.Printf("%+v\n", ctx) - fmt.Println("===================================") + w := ctx.Option.DebugOut + fmt.Fprintln(w, "=============[DEBUG]===============") + fmt.Fprintln(w, "* [TYPE]") + fmt.Fprintln(w, codeSet.Type) + fmt.Fprintf(w, "\n") + fmt.Fprintln(w, "* [ALL OPCODE]") + fmt.Fprintln(w, code.Dump()) + fmt.Fprintf(w, "\n") + fmt.Fprintln(w, "* [CONTEXT]") + fmt.Fprintf(w, "%+v\n", ctx) + fmt.Fprintln(w, "===================================") panic(err) } }() diff --git a/internal/encoder/vm_color/debug_vm.go b/internal/encoder/vm_color/debug_vm.go index 6a6a33d..925f61e 100644 --- a/internal/encoder/vm_color/debug_vm.go +++ b/internal/encoder/vm_color/debug_vm.go @@ -16,16 +16,17 @@ func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) defer func() { if err := recover(); err != nil { - fmt.Println("=============[DEBUG]===============") - fmt.Println("* [TYPE]") - fmt.Println(codeSet.Type) - fmt.Printf("\n") - fmt.Println("* [ALL OPCODE]") - fmt.Println(code.Dump()) - fmt.Printf("\n") - fmt.Println("* [CONTEXT]") - fmt.Printf("%+v\n", ctx) - fmt.Println("===================================") + w := ctx.Option.DebugOut + fmt.Fprintln(w, "=============[DEBUG]===============") + fmt.Fprintln(w, "* [TYPE]") + fmt.Fprintln(w, codeSet.Type) + fmt.Fprintf(w, "\n") + fmt.Fprintln(w, "* [ALL OPCODE]") + fmt.Fprintln(w, code.Dump()) + fmt.Fprintf(w, "\n") + fmt.Fprintln(w, "* [CONTEXT]") + fmt.Fprintf(w, "%+v\n", ctx) + fmt.Fprintln(w, "===================================") panic(err) } }() diff --git a/internal/encoder/vm_color_indent/debug_vm.go b/internal/encoder/vm_color_indent/debug_vm.go index a68bbf6..dd4cd48 100644 --- a/internal/encoder/vm_color_indent/debug_vm.go +++ b/internal/encoder/vm_color_indent/debug_vm.go @@ -16,16 +16,17 @@ func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) defer func() { if err := recover(); err != nil { - fmt.Println("=============[DEBUG]===============") - fmt.Println("* [TYPE]") - fmt.Println(codeSet.Type) - fmt.Printf("\n") - fmt.Println("* [ALL OPCODE]") - fmt.Println(code.Dump()) - fmt.Printf("\n") - fmt.Println("* [CONTEXT]") - fmt.Printf("%+v\n", ctx) - fmt.Println("===================================") + w := ctx.Option.DebugOut + fmt.Fprintln(w, "=============[DEBUG]===============") + fmt.Fprintln(w, "* [TYPE]") + fmt.Fprintln(w, codeSet.Type) + fmt.Fprintf(w, "\n") + fmt.Fprintln(w, "* [ALL OPCODE]") + fmt.Fprintln(w, code.Dump()) + fmt.Fprintf(w, "\n") + fmt.Fprintln(w, "* [CONTEXT]") + fmt.Fprintf(w, "%+v\n", ctx) + fmt.Fprintln(w, "===================================") panic(err) } }() diff --git a/internal/encoder/vm_indent/debug_vm.go b/internal/encoder/vm_indent/debug_vm.go index 4cfd17a..9939538 100644 --- a/internal/encoder/vm_indent/debug_vm.go +++ b/internal/encoder/vm_indent/debug_vm.go @@ -16,16 +16,17 @@ func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) defer func() { if err := recover(); err != nil { - fmt.Println("=============[DEBUG]===============") - fmt.Println("* [TYPE]") - fmt.Println(codeSet.Type) - fmt.Printf("\n") - fmt.Println("* [ALL OPCODE]") - fmt.Println(code.Dump()) - fmt.Printf("\n") - fmt.Println("* [CONTEXT]") - fmt.Printf("%+v\n", ctx) - fmt.Println("===================================") + w := ctx.Option.DebugOut + fmt.Fprintln(w, "=============[DEBUG]===============") + fmt.Fprintln(w, "* [TYPE]") + fmt.Fprintln(w, codeSet.Type) + fmt.Fprintf(w, "\n") + fmt.Fprintln(w, "* [ALL OPCODE]") + fmt.Fprintln(w, code.Dump()) + fmt.Fprintf(w, "\n") + fmt.Fprintln(w, "* [CONTEXT]") + fmt.Fprintf(w, "%+v\n", ctx) + fmt.Fprintln(w, "===================================") panic(err) } }() diff --git a/option.go b/option.go index 0138d77..af400a4 100644 --- a/option.go +++ b/option.go @@ -1,6 +1,8 @@ package json import ( + "io" + "github.com/goccy/go-json/internal/decoder" "github.com/goccy/go-json/internal/encoder" ) @@ -39,6 +41,13 @@ func Debug() EncodeOptionFunc { } } +// DebugWith sets the destination to write debug messages. +func DebugWith(w io.Writer) EncodeOptionFunc { + return func(opt *EncodeOption) { + opt.DebugOut = w + } +} + // Colorize add an identifier for coloring to the string of the encoded result. func Colorize(scheme *ColorScheme) EncodeOptionFunc { return func(opt *EncodeOption) {