wip: decoder errors
This commit is contained in:
@@ -19,7 +19,7 @@ func parseInteger(b []byte) (int64, error) {
|
|||||||
case 'o':
|
case 'o':
|
||||||
return parseIntOct(b)
|
return parseIntOct(b)
|
||||||
default:
|
default:
|
||||||
return 0, fmt.Errorf("invalid base: '%c'", b[1])
|
return 0, newDecodeError(b[1:2], "invalid base: '%c'", b[1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return parseIntDec(b)
|
return parseIntDec(b)
|
||||||
|
|||||||
@@ -22,6 +22,24 @@ type DecodeError struct {
|
|||||||
human string
|
human string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// internal version of DecodeError that is used as the base to create a
|
||||||
|
// DecodeError with full context.
|
||||||
|
type decodeError struct {
|
||||||
|
highlight []byte
|
||||||
|
message string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (de *decodeError) Error() string {
|
||||||
|
return de.message
|
||||||
|
}
|
||||||
|
|
||||||
|
func newDecodeError(highlight []byte, format string, args ...interface{}) error {
|
||||||
|
return &decodeError{
|
||||||
|
highlight: highlight,
|
||||||
|
message: fmt.Sprintf(format, args...),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Error returns the error message contained in the DecodeError.
|
// Error returns the error message contained in the DecodeError.
|
||||||
func (e *DecodeError) Error() string {
|
func (e *DecodeError) Error() string {
|
||||||
return e.message
|
return e.message
|
||||||
@@ -45,15 +63,18 @@ func (e *DecodeError) Position() (row int, column int) {
|
|||||||
//
|
//
|
||||||
// The function copies all bytes used in DecodeError, so that document and
|
// The function copies all bytes used in DecodeError, so that document and
|
||||||
// highlight can be freely deallocated.
|
// highlight can be freely deallocated.
|
||||||
func decodeErrorFromHighlight(document []byte, highlight []byte, message string) error {
|
func wrapDecodeError(document []byte, de *decodeError) error {
|
||||||
|
if de == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
err := &DecodeError{
|
err := &DecodeError{
|
||||||
message: message,
|
message: de.message,
|
||||||
}
|
}
|
||||||
|
|
||||||
offset := unsafe.SubsliceOffset(document, highlight)
|
offset := unsafe.SubsliceOffset(document, de.highlight)
|
||||||
|
|
||||||
err.line, err.column = positionAtEnd(document[:offset])
|
err.line, err.column = positionAtEnd(document[:offset])
|
||||||
before, after := linesOfContext(document, highlight, offset, 3)
|
before, after := linesOfContext(document, de.highlight, offset, 3)
|
||||||
|
|
||||||
var buf strings.Builder
|
var buf strings.Builder
|
||||||
|
|
||||||
@@ -74,7 +95,7 @@ func decodeErrorFromHighlight(document []byte, highlight []byte, message string)
|
|||||||
if len(before) > 0 {
|
if len(before) > 0 {
|
||||||
buf.Write(before[0])
|
buf.Write(before[0])
|
||||||
}
|
}
|
||||||
buf.Write(highlight)
|
buf.Write(de.highlight)
|
||||||
if len(after) > 0 {
|
if len(after) > 0 {
|
||||||
buf.Write(after[0])
|
buf.Write(after[0])
|
||||||
}
|
}
|
||||||
@@ -84,7 +105,7 @@ func decodeErrorFromHighlight(document []byte, highlight []byte, message string)
|
|||||||
if len(before) > 0 {
|
if len(before) > 0 {
|
||||||
buf.WriteString(strings.Repeat(" ", len(before[0])))
|
buf.WriteString(strings.Repeat(" ", len(before[0])))
|
||||||
}
|
}
|
||||||
buf.WriteString(strings.Repeat("~", len(highlight)))
|
buf.WriteString(strings.Repeat("~", len(de.highlight)))
|
||||||
buf.WriteString(" ")
|
buf.WriteString(" ")
|
||||||
buf.WriteString(err.message)
|
buf.WriteString(err.message)
|
||||||
|
|
||||||
|
|||||||
+4
-1
@@ -136,7 +136,10 @@ before `, "highlighted", ``},
|
|||||||
doc := b.Bytes()
|
doc := b.Bytes()
|
||||||
hl := doc[start:end]
|
hl := doc[start:end]
|
||||||
|
|
||||||
err := decodeErrorFromHighlight(doc, hl, e.msg)
|
err := wrapDecodeError(doc, &decodeError{
|
||||||
|
highlight: hl,
|
||||||
|
message: e.msg,
|
||||||
|
})
|
||||||
derr := err.(*DecodeError)
|
derr := err.(*DecodeError)
|
||||||
assert.Equal(t, strings.Trim(e.expected, "\n"), derr.String())
|
assert.Equal(t, strings.Trim(e.expected, "\n"), derr.String())
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -66,6 +66,17 @@ func (d *decoder) arrayIndex(append bool, v reflect.Value) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *decoder) FromParser(p *parser, v interface{}) error {
|
func (d *decoder) FromParser(p *parser, v interface{}) error {
|
||||||
|
err := d.fromParser(p, v)
|
||||||
|
if err != nil {
|
||||||
|
de, ok := err.(*decodeError)
|
||||||
|
if ok {
|
||||||
|
err = wrapDecodeError(p.data, de)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *decoder) fromParser(p *parser, v interface{}) error {
|
||||||
r := reflect.ValueOf(v)
|
r := reflect.ValueOf(v)
|
||||||
if r.Kind() != reflect.Ptr {
|
if r.Kind() != reflect.Ptr {
|
||||||
return fmt.Errorf("need to target a pointer, not %s", r.Kind())
|
return fmt.Errorf("need to target a pointer, not %s", r.Kind())
|
||||||
|
|||||||
Reference in New Issue
Block a user