feat: carry the byte offset and column in SyntaxError
Test / test (push) Canceled after 2m28s

Assisted-by: GLM 5.3 Flash
This commit is contained in:
2026-09-21 23:55:58 +02:00
parent 3cc168f39a
commit 10d49fbe60
5 changed files with 120 additions and 17 deletions
+32 -4
View File
@@ -21,24 +21,52 @@
package interpres
import (
"bytes"
"context"
"errors"
"fmt"
"os"
"slices"
"strings"
)
// A SyntaxError describes a malformed TOML document, including the 1-based
// line on which the problem was detected.
// A SyntaxError describes a malformed TOML document. Line is the 1-based line
// the problem was detected on. Offset is the byte offset in the input the scan
// stopped at, and Column is the 1-based column on that line; both are new in
// 2.0 and a struct literal that names Line and Msg alone still builds.
type SyntaxError struct {
Line int
Msg string
Line int
Offset int
Column int
Msg string
}
func (e *SyntaxError) Error() string {
return fmt.Sprintf("interpres: line %d: %s", e.Line, e.Msg)
}
// SourceLine returns the source line the error points at, rendered from src,
// followed by a caret line marking the column. It is meant for a message the
// reader sees under the input:
//
// port = = 8080
// ^
//
// The caret sits at Offset when it falls inside src, and at the start of the
// line when the error carries no position.
func (e *SyntaxError) SourceLine(src []byte) string {
off := min(e.Offset, len(src))
start := 0
if i := bytes.LastIndexByte(src[:off], '\n'); i >= 0 {
start = i + 1
}
end := len(src)
if i := bytes.IndexByte(src[start:], '\n'); i >= 0 {
end = start + i
}
return string(src[start:end]) + "\n" + strings.Repeat(" ", off-start) + "^"
}
// A DecodeError wraps a decoding failure with the key path at which it
// happened. Path lists one segment per level from the document root, the
// outermost key first: a key contributes its name and an array element its