Give the help examples that read no data and the exit codes, say a data path is no directory in one shape, suggest a record of one for a choice, name a JSON syntax error's line and column, and say no data is loaded from FakeStruct
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
package datafiles
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
@@ -91,15 +92,25 @@ func (s Source) check() error {
|
||||
return fmt.Errorf("a data path is empty")
|
||||
}
|
||||
info, err := os.Stat(s.label)
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
return noDirectory(s.label)
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("data path %s: %w", s.label, err)
|
||||
}
|
||||
if !info.IsDir() {
|
||||
return fmt.Errorf("%s is not a directory", s.label)
|
||||
return fmt.Errorf("data path %s: not a directory", s.label)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// noDirectory is a data path naming nothing, which errors.Is still matches as fs.ErrNotExist.
|
||||
type noDirectory string
|
||||
|
||||
func (d noDirectory) Error() string { return "data path " + string(d) + ": no such directory" }
|
||||
|
||||
func (noDirectory) Unwrap() error { return fs.ErrNotExist }
|
||||
|
||||
// walkDir walks the folder that dir names, and reports whether it handed over any category.
|
||||
func (s Source) walkDir(dir []string, compile func(Category) error) (bool, error) {
|
||||
full := s.dirPath(dir)
|
||||
|
||||
@@ -4,7 +4,9 @@ package jsonvalue
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// Value is a JSON value that only Decode, String and Object make, so a template never compiles
|
||||
@@ -15,7 +17,7 @@ type Value struct{ v any }
|
||||
func Decode(b []byte) (Value, error) {
|
||||
var v any
|
||||
if !json.Valid(b) {
|
||||
return Value{}, json.Unmarshal(b, &v)
|
||||
return Value{}, located(b, json.Unmarshal(b, &v))
|
||||
}
|
||||
dec := json.NewDecoder(bytes.NewReader(b))
|
||||
dec.UseNumber()
|
||||
@@ -23,6 +25,18 @@ func Decode(b []byte) (Value, error) {
|
||||
return Value{v}, err
|
||||
}
|
||||
|
||||
// located prefixes a syntax error with the line and column of the byte it stopped at.
|
||||
func located(b []byte, err error) error {
|
||||
var syntax *json.SyntaxError
|
||||
if !errors.As(err, &syntax) {
|
||||
return err
|
||||
}
|
||||
before := b[:max(syntax.Offset-1, 0)]
|
||||
line := bytes.Count(before, []byte("\n")) + 1
|
||||
column := utf8.RuneCount(before[bytes.LastIndexByte(before, '\n')+1:]) + 1
|
||||
return fmt.Errorf("line %d, column %d: %w", line, column, err)
|
||||
}
|
||||
|
||||
// String is the JSON string s.
|
||||
func String(s string) Value { return Value{s} }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user