Skip to content

Commit

Permalink
PoC for goccy#4
Browse files Browse the repository at this point in the history
  • Loading branch information
lestrrat committed Oct 24, 2019
1 parent 338070f commit d6a5e04
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 15 deletions.
2 changes: 1 addition & 1 deletion decode.go
Expand Up @@ -10,7 +10,7 @@ import (
"reflect"

"github.com/goccy/go-yaml/ast"
"github.com/goccy/go-yaml/errors"
"github.com/goccy/go-yaml/internal/errors"
"github.com/goccy/go-yaml/lexer"
"github.com/goccy/go-yaml/parser"
"github.com/goccy/go-yaml/token"
Expand Down
22 changes: 22 additions & 0 deletions decode_test.go
Expand Up @@ -343,3 +343,25 @@ items:
t.Fatal("failed to decode with merge key")
}
}

func TestDecoder_InvalidCases(t *testing.T) {
const src = `---
a:
- b
c: d
`
var v struct {
A []string
}
err := yaml.NewDecoder(strings.NewReader(src)).Decode(&v)
if err == nil {
t.Fatalf("expected error")
}

//TODO: properly check if errors are colored/have source
t.Logf("%s", err)
t.Logf("%s", yaml.FormatError(err, true, false))
t.Logf("%s", yaml.FormatError(err, false, true))
t.Logf("%s", yaml.FormatError(err, true, true))
}

2 changes: 1 addition & 1 deletion encode.go
Expand Up @@ -10,7 +10,7 @@ import (
"strings"

"github.com/goccy/go-yaml/ast"
"github.com/goccy/go-yaml/errors"
"github.com/goccy/go-yaml/internal/errors"
"github.com/goccy/go-yaml/printer"
"github.com/goccy/go-yaml/token"
"golang.org/x/xerrors"
Expand Down
61 changes: 50 additions & 11 deletions errors/error.go → internal/errors/error.go
@@ -1,6 +1,7 @@
package errors

import (
"bytes"
"fmt"

"github.com/goccy/go-yaml/printer"
Expand Down Expand Up @@ -66,6 +67,16 @@ type wrapError struct {
frame xerrors.Frame
}

type myprinter struct {
xerrors.Printer
colored bool
inclSource bool
}

func (e *wrapError) PrettyPrint(p xerrors.Printer, colored, inclSource bool) error {
return e.FormatError(&myprinter{Printer: p, colored: colored, inclSource: inclSource})
}

func (e *wrapError) FormatError(p xerrors.Printer) error {
if e.verb == 'v' && e.state.Flag('+') {
// print stack trace for debugging
Expand Down Expand Up @@ -134,25 +145,53 @@ type syntaxError struct {
frame xerrors.Frame
}

func (e *syntaxError) PrettyPrint(p xerrors.Printer, colored, inclSource bool) error {
return e.FormatError(&myprinter{Printer: p, colored: colored, inclSource: inclSource})
}

func (e *syntaxError) FormatError(p xerrors.Printer) error {
var pp printer.Printer

var colored, inclSource bool
if mp,ok := p.(*myprinter); ok {
colored = mp.colored
inclSource = mp.inclSource
}

pos := fmt.Sprintf("[%d:%d] ", e.token.Position.Line, e.token.Position.Column)
msg := pp.PrintErrorMessage(fmt.Sprintf("%s%s", pos, e.msg), colored)
if inclSource {
msg += "\n" + pp.PrintErrorToken(e.token, colored)
}
p.Print(msg)

if e.verb == 'v' && e.state.Flag('+') {
// %+v
// print stack trace for debugging
p.Print(e.Error())
e.frame.Format(p)
} else {
p.Print(e.Error())
}
return nil
}

type PrettyPrinter interface {
PrettyPrint(xerrors.Printer, bool, bool) error
}
type Sink struct{ *bytes.Buffer }

func (es *Sink) Print(args ...interface{}) {
fmt.Fprint(es.Buffer, args...)
}

func (es *Sink) Printf(f string, args ...interface{}) {
fmt.Fprintf(es.Buffer, f, args...)
}

func (es *Sink) Detail() bool {
return false
}

func (e *syntaxError) Error() string {
var p printer.Printer
pos := fmt.Sprintf("[%d:%d] ", e.token.Position.Line, e.token.Position.Column)
msg := p.PrintErrorMessage(fmt.Sprintf("syntax error: %s%s", pos, e.msg), ColoredErr)
if WithSourceCode {
err := p.PrintErrorToken(e.token, ColoredErr)
return fmt.Sprintf("%s\n%s", msg, err)
}
return msg
var buf bytes.Buffer
e.PrettyPrint(&Sink{&buf}, false, false)
return buf.String()
}
2 changes: 1 addition & 1 deletion parser/parser.go
Expand Up @@ -4,7 +4,7 @@ import (
"strings"

"github.com/goccy/go-yaml/ast"
"github.com/goccy/go-yaml/errors"
"github.com/goccy/go-yaml/internal/errors"
"github.com/goccy/go-yaml/token"
)

Expand Down
15 changes: 14 additions & 1 deletion yaml.go
Expand Up @@ -3,7 +3,8 @@ package yaml
import (
"bytes"

"github.com/goccy/go-yaml/errors"
"github.com/goccy/go-yaml/internal/errors"
"golang.org/x/xerrors"
)

// Marshaler interface may be implemented by types to customize their
Expand Down Expand Up @@ -111,3 +112,15 @@ func Unmarshal(data []byte, v interface{}) error {
}
return nil
}

func FormatError(e error, colored, inclSource bool) string {
var pp errors.PrettyPrinter
if xerrors.As(e, &pp) {
var buf bytes.Buffer
pp.PrettyPrint(&errors.Sink{&buf}, colored, inclSource)
return buf.String()
}

return e.Error()

}

0 comments on commit d6a5e04

Please sign in to comment.