Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
c597be1ce6 |
@ -20,9 +20,9 @@ func BenchmarkRetrieveSimpleValues(b *testing.B) {
|
|||||||
|
|
||||||
// Parse once before benchmarking retrieval
|
// Parse once before benchmarking retrieval
|
||||||
reader := strings.NewReader(configData)
|
reader := strings.NewReader(configData)
|
||||||
cfg, err := config.Load(reader)
|
cfg := config.Load(reader)
|
||||||
if err != nil {
|
if cfg.HasError() {
|
||||||
b.Fatalf("Failed to parse config: %v", err)
|
b.Fatalf("Failed to parse config: %v", cfg.GetError().Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
@ -75,9 +75,9 @@ func BenchmarkRetrieveNestedValues(b *testing.B) {
|
|||||||
|
|
||||||
// Parse once before benchmarking retrieval
|
// Parse once before benchmarking retrieval
|
||||||
reader := strings.NewReader(configData)
|
reader := strings.NewReader(configData)
|
||||||
cfg, err := config.Load(reader)
|
cfg := config.Load(reader)
|
||||||
if err != nil {
|
if cfg.HasError() {
|
||||||
b.Fatalf("Failed to parse config: %v", err)
|
b.Fatalf("Failed to parse config: %v", cfg.GetError().Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
@ -125,9 +125,9 @@ func BenchmarkRetrieveArrayValues(b *testing.B) {
|
|||||||
|
|
||||||
// Parse once before benchmarking retrieval
|
// Parse once before benchmarking retrieval
|
||||||
reader := strings.NewReader(configData)
|
reader := strings.NewReader(configData)
|
||||||
cfg, err := config.Load(reader)
|
cfg := config.Load(reader)
|
||||||
if err != nil {
|
if cfg.HasError() {
|
||||||
b.Fatalf("Failed to parse config: %v", err)
|
b.Fatalf("Failed to parse config: %v", cfg.GetError().Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
@ -180,9 +180,9 @@ func BenchmarkRetrieveMixedValues(b *testing.B) {
|
|||||||
|
|
||||||
// Parse once before benchmarking retrieval
|
// Parse once before benchmarking retrieval
|
||||||
reader := strings.NewReader(configData)
|
reader := strings.NewReader(configData)
|
||||||
cfg, err := config.Load(reader)
|
cfg := config.Load(reader)
|
||||||
if err != nil {
|
if cfg.HasError() {
|
||||||
b.Fatalf("Failed to parse config: %v", err)
|
b.Fatalf("Failed to parse config: %v", cfg.GetError().Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
@ -531,14 +531,14 @@ write = 10
|
|||||||
|
|
||||||
// Custom config
|
// Custom config
|
||||||
customReader := strings.NewReader(customConfig)
|
customReader := strings.NewReader(customConfig)
|
||||||
customCfg, err := config.Load(customReader)
|
customCfg := config.Load(customReader)
|
||||||
if err != nil {
|
if customCfg.HasError() {
|
||||||
b.Fatalf("Failed to parse custom config: %v", err)
|
b.Fatalf("Failed to parse custom config: %v", customCfg.GetError().Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSON config
|
// JSON config
|
||||||
var jsonResult map[string]any
|
var jsonResult map[string]any
|
||||||
err = json.Unmarshal([]byte(jsonConfig), &jsonResult)
|
err := json.Unmarshal([]byte(jsonConfig), &jsonResult)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatalf("Failed to parse JSON: %v", err)
|
b.Fatalf("Failed to parse JSON: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -23,9 +23,9 @@ func BenchmarkSmallConfig(b *testing.B) {
|
|||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
reader := strings.NewReader(smallConfig)
|
reader := strings.NewReader(smallConfig)
|
||||||
_, err := config.Load(reader)
|
cfg := config.Load(reader)
|
||||||
if err != nil {
|
if cfg.HasError() {
|
||||||
b.Fatalf("Failed to parse small config: %v", err)
|
b.Fatalf("Failed to parse small config: %v", cfg.GetError().Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -74,9 +74,9 @@ func BenchmarkMediumConfig(b *testing.B) {
|
|||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
reader := strings.NewReader(mediumConfig)
|
reader := strings.NewReader(mediumConfig)
|
||||||
_, err := config.Load(reader)
|
cfg := config.Load(reader)
|
||||||
if err != nil {
|
if cfg.HasError() {
|
||||||
b.Fatalf("Failed to parse medium config: %v", err)
|
b.Fatalf("Failed to parse small config: %v", cfg.GetError().Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -170,9 +170,9 @@ func BenchmarkLargeConfig(b *testing.B) {
|
|||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
reader := strings.NewReader(largeConfig)
|
reader := strings.NewReader(largeConfig)
|
||||||
_, err := config.Load(reader)
|
cfg := config.Load(reader)
|
||||||
if err != nil {
|
if cfg.HasError() {
|
||||||
b.Fatalf("Failed to parse large config: %v", err)
|
b.Fatalf("Failed to parse small config: %v", cfg.GetError().Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
30
data.go
30
data.go
@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"maps"
|
"maps"
|
||||||
|
"os"
|
||||||
"slices"
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
@ -15,6 +16,7 @@ type Data struct {
|
|||||||
currentObject map[string]any
|
currentObject map[string]any
|
||||||
stack []map[string]any
|
stack []map[string]any
|
||||||
currentToken Token
|
currentToken Token
|
||||||
|
lastError error
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewData() *Data {
|
func NewData() *Data {
|
||||||
@ -485,14 +487,36 @@ func (d *Data) parseObject() (any, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Load(r io.Reader) (*Data, error) {
|
func Load(r io.Reader) *Data {
|
||||||
data := NewData()
|
data := NewData()
|
||||||
err := data.Parse(r)
|
err := data.Parse(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
data.Release()
|
data.Release()
|
||||||
return nil, err
|
emptyData := NewData()
|
||||||
|
emptyData.lastError = err
|
||||||
|
return emptyData
|
||||||
}
|
}
|
||||||
return data, nil
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoadFromFile(filepath string) *Data {
|
||||||
|
file, err := os.Open(filepath)
|
||||||
|
if err != nil {
|
||||||
|
emptyData := NewData()
|
||||||
|
emptyData.lastError = err
|
||||||
|
return emptyData
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
return Load(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Data) HasError() bool {
|
||||||
|
return d.lastError != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Data) GetError() error {
|
||||||
|
return d.lastError
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Data) tokenToValue(token Token) any {
|
func (d *Data) tokenToValue(token Token) any {
|
||||||
|
@ -18,9 +18,9 @@ func TestBasicKeyValuePairs(t *testing.T) {
|
|||||||
negativeFloat -2.5
|
negativeFloat -2.5
|
||||||
stringValue "hello world"
|
stringValue "hello world"
|
||||||
`
|
`
|
||||||
config, err := fin.Load(strings.NewReader(input))
|
config := fin.Load(strings.NewReader(input))
|
||||||
if err != nil {
|
if config.HasError() {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", config.GetError().Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify boolean values
|
// Verify boolean values
|
||||||
@ -98,9 +98,9 @@ func TestComments(t *testing.T) {
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
config, err := fin.Load(strings.NewReader(input))
|
config := fin.Load(strings.NewReader(input))
|
||||||
if err != nil {
|
if config.HasError() {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", config.GetError().Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify that comments are properly ignored and values are parsed
|
// Verify that comments are properly ignored and values are parsed
|
||||||
@ -144,9 +144,9 @@ func TestArrays(t *testing.T) {
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
config, err := fin.Load(strings.NewReader(input))
|
config := fin.Load(strings.NewReader(input))
|
||||||
if err != nil {
|
if config.HasError() {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", config.GetError().Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify simple array
|
// Verify simple array
|
||||||
@ -221,9 +221,9 @@ func TestMaps(t *testing.T) {
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
config, err := fin.Load(strings.NewReader(input))
|
config := fin.Load(strings.NewReader(input))
|
||||||
if err != nil {
|
if config.HasError() {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", config.GetError().Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify simple map
|
// Verify simple map
|
||||||
|
@ -28,9 +28,9 @@ func TestBasicWrite(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read back
|
// Read back
|
||||||
readData, err := fin.Load(bytes.NewReader(buf.Bytes()))
|
readData := fin.Load(bytes.NewReader(buf.Bytes()))
|
||||||
if err != nil {
|
if readData.HasError() {
|
||||||
t.Fatalf("unexpected error loading written data: %v", err)
|
t.Fatalf("unexpected error loading written data: %v", readData.GetError().Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify values
|
// Verify values
|
||||||
@ -72,9 +72,9 @@ func TestArrayWrite(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read back
|
// Read back
|
||||||
readData, err := fin.Load(bytes.NewReader(buf.Bytes()))
|
readData := fin.Load(bytes.NewReader(buf.Bytes()))
|
||||||
if err != nil {
|
if readData.HasError() {
|
||||||
t.Fatalf("unexpected error loading written data: %v", err)
|
t.Fatalf("unexpected error loading written data: %v", readData.GetError().Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify arrays
|
// Verify arrays
|
||||||
@ -149,9 +149,9 @@ func TestMapWrite(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read back
|
// Read back
|
||||||
readData, err := fin.Load(bytes.NewReader(buf.Bytes()))
|
readData := fin.Load(bytes.NewReader(buf.Bytes()))
|
||||||
if err != nil {
|
if readData.HasError() {
|
||||||
t.Fatalf("unexpected error loading written data: %v", err)
|
t.Fatalf("unexpected error loading written data: %v", readData.GetError().Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify simple map
|
// Verify simple map
|
||||||
@ -198,9 +198,9 @@ func TestSpecialCasesWrite(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read back
|
// Read back
|
||||||
readData, err := fin.Load(bytes.NewReader(buf.Bytes()))
|
readData := fin.Load(bytes.NewReader(buf.Bytes()))
|
||||||
if err != nil {
|
if readData.HasError() {
|
||||||
t.Fatalf("unexpected error loading written data: %v", err)
|
t.Fatalf("unexpected error loading written data: %v", readData.GetError().Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify combined value+object
|
// Verify combined value+object
|
||||||
@ -231,9 +231,9 @@ func TestStringEscapingWrite(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read back
|
// Read back
|
||||||
readData, err := fin.Load(bytes.NewReader(buf.Bytes()))
|
readData := fin.Load(bytes.NewReader(buf.Bytes()))
|
||||||
if err != nil {
|
if readData.HasError() {
|
||||||
t.Fatalf("unexpected error loading written data: %v", err)
|
t.Fatalf("unexpected error loading written data: %v", readData.GetError().Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify escaped strings
|
// Verify escaped strings
|
||||||
|
Loading…
x
Reference in New Issue
Block a user