summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2023-02-25 17:12:39 -0700
committerLuke Shumaker <lukeshu@lukeshu.com>2023-02-25 17:12:39 -0700
commit7301cd6c4e97b272bd708d4c87d26609510e6ca7 (patch)
tree6ecce72f45f255dad80cbe16d77503ca02c2ce23
parente38edfa53173c054ff97a5c51f90df0da60f16f5 (diff)
jsonparse: Define an InvalidCharacterError type instead of using fmt.Errorf
-rw-r--r--internal/jsonparse/parse.go35
1 files changed, 22 insertions, 13 deletions
diff --git a/internal/jsonparse/parse.go b/internal/jsonparse/parse.go
index c641f1b..214e3ba 100644
--- a/internal/jsonparse/parse.go
+++ b/internal/jsonparse/parse.go
@@ -14,6 +14,15 @@ import (
var ErrParserExceededMaxDepth = errors.New("exceeded max depth")
+type InvalidCharacterError struct {
+ Char rune
+ Where string
+}
+
+func (e *InvalidCharacterError) Error() string {
+ return fmt.Sprintf("invalid character %q %s", e.Char, e.Where)
+}
+
func isHex(c rune) bool {
return ('0' <= c && c <= '9') ||
('a' <= c && c <= 'f') ||
@@ -571,7 +580,7 @@ func (par *Parser) HandleRune(c rune) (RuneType, error) {
if len(par.barriers) > 0 {
return RuneTypeEOF, nil
} else {
- return RuneTypeError, fmt.Errorf("invalid character %q after top-level value", c)
+ return RuneTypeError, &InvalidCharacterError{c, "after top-level value"}
}
}
switch par.stack[len(par.stack)-1] {
@@ -605,7 +614,7 @@ func (par *Parser) HandleRune(c rune) (RuneType, error) {
case 'n':
return par.replaceState(RuneTypeNullN), nil
default:
- return RuneTypeError, fmt.Errorf("invalid character %q looking for beginning of value", c)
+ return RuneTypeError, &InvalidCharacterError{c, "looking for beginning of value"}
}
// object //////////////////////////////////////////////////////////////////////////////////
case RuneTypeObjectBeg: // waiting for key to start or '}'
@@ -619,7 +628,7 @@ func (par *Parser) HandleRune(c rune) (RuneType, error) {
par.popState()
return RuneTypeObjectEnd, nil
default:
- return RuneTypeError, fmt.Errorf("invalid character %q looking for beginning of object key string", c)
+ return RuneTypeError, &InvalidCharacterError{c, "looking for beginning of object key string"}
}
case RuneTypeStringEnd: // waiting for ':'
switch c {
@@ -630,7 +639,7 @@ func (par *Parser) HandleRune(c rune) (RuneType, error) {
par.pushState(runeTypeAny)
return RuneTypeObjectColon, nil
default:
- return RuneTypeError, fmt.Errorf("invalid character %q after object key", c)
+ return RuneTypeError, &InvalidCharacterError{c, "after object key"}
}
case RuneTypeObjectComma: // waiting for ',' or '}'
switch c {
@@ -643,7 +652,7 @@ func (par *Parser) HandleRune(c rune) (RuneType, error) {
par.popState()
return RuneTypeObjectEnd, nil
default:
- return RuneTypeError, fmt.Errorf("invalid character %q after object key:value pair", c)
+ return RuneTypeError, &InvalidCharacterError{c, "after object key:value pair"}
}
// array ///////////////////////////////////////////////////////////////////////////////////
case RuneTypeArrayBeg: // waiting for item to start or ']'
@@ -669,7 +678,7 @@ func (par *Parser) HandleRune(c rune) (RuneType, error) {
par.popState()
return RuneTypeArrayEnd, nil
default:
- return RuneTypeError, fmt.Errorf("invalid character %q after array element", c)
+ return RuneTypeError, &InvalidCharacterError{c, "after array element"}
}
// string //////////////////////////////////////////////////////////////////////////////////
case RuneTypeStringBeg: // waiting for char or '"'
@@ -682,7 +691,7 @@ func (par *Parser) HandleRune(c rune) (RuneType, error) {
case 0x0020 <= c && c <= 0x10FFFF:
return RuneTypeStringChar, nil
default:
- return RuneTypeError, fmt.Errorf("invalid character %q in string literal", c)
+ return RuneTypeError, &InvalidCharacterError{c, "in string literal"}
}
case RuneTypeStringEsc: // waiting for escape char
switch c {
@@ -692,7 +701,7 @@ func (par *Parser) HandleRune(c rune) (RuneType, error) {
case 'u':
return par.replaceState(RuneTypeStringEscU), nil
default:
- return RuneTypeError, fmt.Errorf("invalid character %q in string escape code", c)
+ return RuneTypeError, &InvalidCharacterError{c, "in string escape code"}
}
case RuneTypeStringEscU:
if !isHex(c) {
@@ -762,7 +771,7 @@ func (par *Parser) HandleRune(c rune) (RuneType, error) {
case '1', '2', '3', '4', '5', '6', '7', '8', '9':
return par.replaceState(RuneTypeNumberIntDig), nil
default:
- return RuneTypeError, fmt.Errorf("invalid character %q in numeric literal", c)
+ return RuneTypeError, &InvalidCharacterError{c, "in numeric literal"}
}
case RuneTypeNumberIntZero: // C
switch c {
@@ -791,7 +800,7 @@ func (par *Parser) HandleRune(c rune) (RuneType, error) {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
return par.replaceState(RuneTypeNumberFracDig), nil
default:
- return RuneTypeError, fmt.Errorf("invalid character %q after decimal point in numeric literal", c)
+ return RuneTypeError, &InvalidCharacterError{c, "after decimal point in numeric literal"}
}
case RuneTypeNumberFracDig: // F
switch c {
@@ -810,14 +819,14 @@ func (par *Parser) HandleRune(c rune) (RuneType, error) {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
return par.replaceState(RuneTypeNumberExpDig), nil
default:
- return RuneTypeError, fmt.Errorf("invalid character %q in exponent of numeric literal", c)
+ return RuneTypeError, &InvalidCharacterError{c, "in exponent of numeric literal"}
}
case RuneTypeNumberExpSign: // H
switch c {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
return par.replaceState(RuneTypeNumberExpDig), nil
default:
- return RuneTypeError, fmt.Errorf("invalid character %q in exponent of numeric literal", c)
+ return RuneTypeError, &InvalidCharacterError{c, "in exponent of numeric literal"}
}
case RuneTypeNumberExpDig: // I
switch c {
@@ -858,7 +867,7 @@ func (par *Parser) HandleRune(c rune) (RuneType, error) {
func (par *Parser) expectRune(c, exp rune, typ RuneType, context string, pop bool) (RuneType, error) {
if c != exp {
- return RuneTypeError, fmt.Errorf("invalid character %q in literal %s (expecting %q)", c, context, exp)
+ return RuneTypeError, &InvalidCharacterError{c, fmt.Sprintf("in literal %s (expecting %q)", context, exp)}
}
if pop {
par.popState()