Merge pull request #40 from pelletier/pelletier/space-in-keys
Accept spaces in keys
This commit is contained in:
@@ -13,7 +13,16 @@ func parseKey(key string) ([]string, error) {
|
|||||||
var buffer bytes.Buffer
|
var buffer bytes.Buffer
|
||||||
inQuotes := false
|
inQuotes := false
|
||||||
escapeNext := false
|
escapeNext := false
|
||||||
|
ignoreSpace := true
|
||||||
|
expectDot := false
|
||||||
|
|
||||||
for _, char := range key {
|
for _, char := range key {
|
||||||
|
if ignoreSpace {
|
||||||
|
if char == ' ' {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ignoreSpace = false
|
||||||
|
}
|
||||||
if escapeNext {
|
if escapeNext {
|
||||||
buffer.WriteRune(char)
|
buffer.WriteRune(char)
|
||||||
escapeNext = false
|
escapeNext = false
|
||||||
@@ -25,18 +34,31 @@ func parseKey(key string) ([]string, error) {
|
|||||||
continue
|
continue
|
||||||
case '"':
|
case '"':
|
||||||
inQuotes = !inQuotes
|
inQuotes = !inQuotes
|
||||||
|
expectDot = false
|
||||||
case '.':
|
case '.':
|
||||||
if inQuotes {
|
if inQuotes {
|
||||||
buffer.WriteRune(char)
|
buffer.WriteRune(char)
|
||||||
} else {
|
} else {
|
||||||
groups = append(groups, buffer.String())
|
groups = append(groups, buffer.String())
|
||||||
buffer.Reset()
|
buffer.Reset()
|
||||||
|
ignoreSpace = true
|
||||||
|
expectDot = false
|
||||||
|
}
|
||||||
|
case ' ':
|
||||||
|
if inQuotes {
|
||||||
|
buffer.WriteRune(char)
|
||||||
|
} else {
|
||||||
|
expectDot = true
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if !inQuotes && !isValidBareChar(char) {
|
if !inQuotes && !isValidBareChar(char) {
|
||||||
return nil, fmt.Errorf("invalid bare character: %c", char)
|
return nil, fmt.Errorf("invalid bare character: %c", char)
|
||||||
}
|
}
|
||||||
|
if !inQuotes && expectDot {
|
||||||
|
return nil, fmt.Errorf("what?")
|
||||||
|
}
|
||||||
buffer.WriteRune(char)
|
buffer.WriteRune(char)
|
||||||
|
expectDot = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if inQuotes {
|
if inQuotes {
|
||||||
|
|||||||
@@ -39,6 +39,15 @@ func TestValidKeyGroup(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNestedQuotedUnicodeKeyGroup(t *testing.T) {
|
||||||
|
testFlow(t, `[ j . "ʞ" . l ]`, []token{
|
||||||
|
token{Position{1, 1}, tokenLeftBracket, "["},
|
||||||
|
token{Position{1, 2}, tokenKeyGroup, ` j . "ʞ" . l `},
|
||||||
|
token{Position{1, 15}, tokenRightBracket, "]"},
|
||||||
|
token{Position{1, 16}, tokenEOF, ""},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestUnclosedKeyGroup(t *testing.T) {
|
func TestUnclosedKeyGroup(t *testing.T) {
|
||||||
testFlow(t, "[hello world", []token{
|
testFlow(t, "[hello world", []token{
|
||||||
token{Position{1, 1}, tokenLeftBracket, "["},
|
token{Position{1, 1}, tokenLeftBracket, "["},
|
||||||
|
|||||||
@@ -157,6 +157,41 @@ func TestNestedKeys(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNestedQuotedUnicodeKeys(t *testing.T) {
|
||||||
|
tree, err := Load("[ j . \"ʞ\" . l ]\nd = 42")
|
||||||
|
assertTree(t, tree, err, map[string]interface{}{
|
||||||
|
"j": map[string]interface{}{
|
||||||
|
"ʞ": map[string]interface{}{
|
||||||
|
"l": map[string]interface{}{
|
||||||
|
"d": int64(42),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
tree, err = Load("[ g . h . i ]\nd = 42")
|
||||||
|
assertTree(t, tree, err, map[string]interface{}{
|
||||||
|
"g": map[string]interface{}{
|
||||||
|
"h": map[string]interface{}{
|
||||||
|
"i": map[string]interface{}{
|
||||||
|
"d": int64(42),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
tree, err = Load("[ d.e.f ]\nk = 42")
|
||||||
|
assertTree(t, tree, err, map[string]interface{}{
|
||||||
|
"d": map[string]interface{}{
|
||||||
|
"e": map[string]interface{}{
|
||||||
|
"f": map[string]interface{}{
|
||||||
|
"k": int64(42),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestArrayOne(t *testing.T) {
|
func TestArrayOne(t *testing.T) {
|
||||||
tree, err := Load("a = [1]")
|
tree, err := Load("a = [1]")
|
||||||
assertTree(t, tree, err, map[string]interface{}{
|
assertTree(t, tree, err, map[string]interface{}{
|
||||||
|
|||||||
Reference in New Issue
Block a user