Multiline literal strings
This commit is contained in:
@@ -92,25 +92,24 @@ func parseKeyval(b []byte) ([]byte, error) {
|
|||||||
func parseVal(b []byte) ([]byte, error) {
|
func parseVal(b []byte) ([]byte, error) {
|
||||||
// val = string / boolean / array / inline-table / date-time / float / integer
|
// val = string / boolean / array / inline-table / date-time / float / integer
|
||||||
|
|
||||||
|
var err error
|
||||||
c := b[0]
|
c := b[0]
|
||||||
|
|
||||||
switch c {
|
switch c {
|
||||||
// strings
|
// strings
|
||||||
case '"':
|
case '"':
|
||||||
var rest []byte
|
|
||||||
var err error
|
|
||||||
if scanFollowsMultilineBasicStringDelimiter(b) {
|
if scanFollowsMultilineBasicStringDelimiter(b) {
|
||||||
_, rest, err = parseMultilineBasicString(b)
|
_, b, err = parseMultilineBasicString(b)
|
||||||
} else {
|
} else {
|
||||||
_, rest, err = parseBasicString(b)
|
_, b, err = parseBasicString(b)
|
||||||
}
|
}
|
||||||
return rest, err
|
return b, err
|
||||||
case '\'':
|
case '\'':
|
||||||
if scanFollowsMultilineLiteralStringDelimiter(b) {
|
if scanFollowsMultilineLiteralStringDelimiter(b) {
|
||||||
return parseMultilineLiteralString(b)
|
_, b, err = parseMultilineLiteralString(b)
|
||||||
}
|
}
|
||||||
_, rest, err := scanLiteralString(b)
|
_, b, err = scanLiteralString(b)
|
||||||
return rest, err
|
return b, err
|
||||||
// TODO boolean
|
// TODO boolean
|
||||||
|
|
||||||
// TODO array
|
// TODO array
|
||||||
@@ -127,6 +126,24 @@ func parseVal(b []byte) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseMultilineLiteralString(b []byte) (string, []byte, error) {
|
||||||
|
token, rest, err := scanMultilineLiteralString(b)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
i := 3
|
||||||
|
|
||||||
|
// skip the immediate new line
|
||||||
|
if token[i] == '\n' {
|
||||||
|
i++
|
||||||
|
} else if token[i] == '\r' && token[i+1] == '\n' {
|
||||||
|
i += 2
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(token[i : len(b)-3]), rest, err
|
||||||
|
}
|
||||||
|
|
||||||
func parseMultilineBasicString(b []byte) (string, []byte, error) {
|
func parseMultilineBasicString(b []byte) (string, []byte, error) {
|
||||||
//ml-basic-string = ml-basic-string-delim [ newline ] ml-basic-body
|
//ml-basic-string = ml-basic-string-delim [ newline ] ml-basic-body
|
||||||
//ml-basic-string-delim
|
//ml-basic-string-delim
|
||||||
|
|||||||
+12
-1
@@ -39,7 +39,7 @@ a = false`,
|
|||||||
`[[foo]]`,
|
`[[foo]]`,
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParse(t *testing.T) {
|
func TestScan(t *testing.T) {
|
||||||
for i, data := range inputs {
|
for i, data := range inputs {
|
||||||
t.Run(fmt.Sprintf("example %d", i), func(t *testing.T) {
|
t.Run(fmt.Sprintf("example %d", i), func(t *testing.T) {
|
||||||
fmt.Printf("input:\n\t`%s`\n", data)
|
fmt.Printf("input:\n\t`%s`\n", data)
|
||||||
@@ -55,6 +55,17 @@ func TestParse(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestParse(t *testing.T) {
|
||||||
|
for i, data := range inputs {
|
||||||
|
t.Run(fmt.Sprintf("example %d", i), func(t *testing.T) {
|
||||||
|
fmt.Printf("input:\n\t`%s`\n", data)
|
||||||
|
b := []byte(data)
|
||||||
|
err := parse(b)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type noopParser struct {
|
type noopParser struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user