Bits of code cleanup, no functional changes.
This commit is contained in:
parent
b1484cb690
commit
febe1ff568
|
@ -65,8 +65,8 @@ const (
|
||||||
// TypeFloat identifies a floating point number (10.1234, 143E-12, 43.28377e+4, +inf, -inf, nan).
|
// TypeFloat identifies a floating point number (10.1234, 143E-12, 43.28377e+4, +inf, -inf, nan).
|
||||||
TypeFloat ValueType = "float"
|
TypeFloat ValueType = "float"
|
||||||
|
|
||||||
// TypeBoolean identifies a boolean value (true or false).
|
// TypeBool identifies a boolean value (true or false).
|
||||||
TypeBoolean ValueType = "boolean"
|
TypeBool ValueType = "bool"
|
||||||
|
|
||||||
// TypeOffsetDateTime identifies a date/time value, including timezone info (2019-06-18 10:32:15.173645362+0200).
|
// TypeOffsetDateTime identifies a date/time value, including timezone info (2019-06-18 10:32:15.173645362+0200).
|
||||||
TypeOffsetDateTime ValueType = "datetime"
|
TypeOffsetDateTime ValueType = "datetime"
|
||||||
|
|
|
@ -12,8 +12,8 @@ func Test_ConstructSlightlyComplexStructure(t *testing.T) {
|
||||||
p.SetKeyValuePair(ast.NewKey("ding"), ast.NewValue(ast.TypeInteger, 10))
|
p.SetKeyValuePair(ast.NewKey("ding"), ast.NewValue(ast.TypeInteger, 10))
|
||||||
p.SetKeyValuePair(ast.NewKey("dong"), ast.NewValue(ast.TypeString, "not a song"))
|
p.SetKeyValuePair(ast.NewKey("dong"), ast.NewValue(ast.TypeString, "not a song"))
|
||||||
p.OpenTable(ast.NewKey("key1", "key2 a"))
|
p.OpenTable(ast.NewKey("key1", "key2 a"))
|
||||||
p.SetKeyValuePair(ast.NewKey("dooh"), ast.NewValue(ast.TypeBoolean, true))
|
p.SetKeyValuePair(ast.NewKey("dooh"), ast.NewValue(ast.TypeBool, true))
|
||||||
p.SetKeyValuePair(ast.NewKey("dah"), ast.NewValue(ast.TypeBoolean, false))
|
p.SetKeyValuePair(ast.NewKey("dah"), ast.NewValue(ast.TypeBool, false))
|
||||||
p.OpenTable(ast.NewKey("key1", "key2 b"))
|
p.OpenTable(ast.NewKey("key1", "key2 b"))
|
||||||
p.SetKeyValuePair(ast.NewKey("dieh"), ast.NewValue(ast.TypeFloat, 1.111))
|
p.SetKeyValuePair(ast.NewKey("dieh"), ast.NewValue(ast.TypeFloat, 1.111))
|
||||||
p.SetKeyValuePair(ast.NewKey("duh"), ast.NewValue(ast.TypeFloat, 1.18e-12))
|
p.SetKeyValuePair(ast.NewKey("duh"), ast.NewValue(ast.TypeFloat, 1.18e-12))
|
||||||
|
@ -188,7 +188,7 @@ func Test_GivenExistingValueAtDeepKeyFromSubTable_CreatingTableAtSameKey_Returns
|
||||||
p := ast.NewDocument()
|
p := ast.NewDocument()
|
||||||
p.OpenTable(ast.NewKey("deep", "table"))
|
p.OpenTable(ast.NewKey("deep", "table"))
|
||||||
p.SetKeyValuePair(ast.NewKey("key1", "key2"), ast.NewValue(ast.TypeInteger, 0))
|
p.SetKeyValuePair(ast.NewKey("key1", "key2"), ast.NewValue(ast.TypeInteger, 0))
|
||||||
return p.SetKeyValuePair(ast.NewKey("key1", "key2"), ast.NewValue(ast.TypeBoolean, true)), p
|
return p.SetKeyValuePair(ast.NewKey("key1", "key2"), ast.NewValue(ast.TypeBool, true)), p
|
||||||
},
|
},
|
||||||
// This test mainly tests the formatting of [deep->table->key1->key2], being a concatenation
|
// This test mainly tests the formatting of [deep->table->key1->key2], being a concatenation
|
||||||
// of the currently active table plus the multipart key for SetKeyValuePair().
|
// of the currently active table plus the multipart key for SetKeyValuePair().
|
||||||
|
|
|
@ -10,13 +10,13 @@ import (
|
||||||
func Test_StringFormatting(t *testing.T) {
|
func Test_StringFormatting(t *testing.T) {
|
||||||
testAST(t, func() (error, *ast.Document) {
|
testAST(t, func() (error, *ast.Document) {
|
||||||
tableData := make(ast.Table)
|
tableData := make(ast.Table)
|
||||||
tableData["x"] = ast.NewValue(ast.TypeBoolean, true)
|
tableData["x"] = ast.NewValue(ast.TypeBool, true)
|
||||||
tableData["y"] = ast.NewValue(ast.TypeInteger, 42)
|
tableData["y"] = ast.NewValue(ast.TypeInteger, 42)
|
||||||
dateTime, _ := time.Parse(time.RFC3339Nano, "2003-11-01T01:02:03.999999999+10:00")
|
dateTime, _ := time.Parse(time.RFC3339Nano, "2003-11-01T01:02:03.999999999+10:00")
|
||||||
doc := ast.NewDocument()
|
doc := ast.NewDocument()
|
||||||
doc.SetKeyValuePair(ast.NewKey("a"), ast.NewValue(ast.TypeInteger, 1))
|
doc.SetKeyValuePair(ast.NewKey("a"), ast.NewValue(ast.TypeInteger, 1))
|
||||||
doc.SetKeyValuePair(ast.NewKey("b"), ast.NewValue(ast.TypeFloat, 2.3))
|
doc.SetKeyValuePair(ast.NewKey("b"), ast.NewValue(ast.TypeFloat, 2.3))
|
||||||
doc.SetKeyValuePair(ast.NewKey("c"), ast.NewValue(ast.TypeBoolean, true))
|
doc.SetKeyValuePair(ast.NewKey("c"), ast.NewValue(ast.TypeBool, true))
|
||||||
doc.SetKeyValuePair(ast.NewKey("d"), ast.NewValue(ast.TypeString, "foo"))
|
doc.SetKeyValuePair(ast.NewKey("d"), ast.NewValue(ast.TypeString, "foo"))
|
||||||
doc.SetKeyValuePair(ast.NewKey("e"), ast.NewValue(ast.TypeArray, ast.NewValue(ast.TypeInteger, 1), ast.NewValue(ast.TypeInteger, 2)))
|
doc.SetKeyValuePair(ast.NewKey("e"), ast.NewValue(ast.TypeArray, ast.NewValue(ast.TypeInteger, 1), ast.NewValue(ast.TypeInteger, 2)))
|
||||||
doc.SetKeyValuePair(ast.NewKey("f"), ast.NewValue(ast.TypeTable, tableData))
|
doc.SetKeyValuePair(ast.NewKey("f"), ast.NewValue(ast.TypeTable, tableData))
|
||||||
|
|
|
@ -53,7 +53,7 @@ func makeSushi(value *ast.Value) string {
|
||||||
return renderValue("integer", fmt.Sprintf("%d", value.Data[0].(int64)))
|
return renderValue("integer", fmt.Sprintf("%d", value.Data[0].(int64)))
|
||||||
case ast.TypeFloat:
|
case ast.TypeFloat:
|
||||||
return renderValue("float", fmt.Sprintf("%v", value.Data[0].(float64)))
|
return renderValue("float", fmt.Sprintf("%v", value.Data[0].(float64)))
|
||||||
case ast.TypeBoolean:
|
case ast.TypeBool:
|
||||||
return renderValue("bool", fmt.Sprintf("%t", value.Data[0].(bool)))
|
return renderValue("bool", fmt.Sprintf("%t", value.Data[0].(bool)))
|
||||||
case ast.TypeOffsetDateTime:
|
case ast.TypeOffsetDateTime:
|
||||||
return renderValue("datetime", value.Data[0].(time.Time).Format(time.RFC3339Nano))
|
return renderValue("datetime", value.Data[0].(time.Time).Format(time.RFC3339Nano))
|
||||||
|
|
|
@ -12,7 +12,7 @@ var (
|
||||||
// Blank is ignored around key names and values. The key, equals
|
// Blank is ignored around key names and values. The key, equals
|
||||||
// sign, and value must be on the same line (though some values can be
|
// sign, and value must be on the same line (though some values can be
|
||||||
// broken over multiple lines).
|
// broken over multiple lines).
|
||||||
keyAssignment = c.Seq(dropBlanks, a.Equal, dropBlanks)
|
keyAssignment = c.Seq(optionalBlanks, a.Equal, optionalBlanks)
|
||||||
|
|
||||||
// A key may be either bare, quoted or dotted. Bare keys may only
|
// A key may be either bare, quoted or dotted. Bare keys may only
|
||||||
// contain ASCII letters, ASCII digits, underscores, and dashes
|
// contain ASCII letters, ASCII digits, underscores, and dashes
|
||||||
|
@ -31,10 +31,7 @@ var (
|
||||||
// This allows for grouping similar properties together. Blanks
|
// This allows for grouping similar properties together. Blanks
|
||||||
// around dot-separated parts are ignored, however, best practice is to
|
// around dot-separated parts are ignored, however, best practice is to
|
||||||
// not use any extraneous blanks.
|
// not use any extraneous blanks.
|
||||||
keySeparatorDot = c.Seq(dropBlanks, a.Dot, dropBlanks)
|
keySeparatorDot = c.Seq(optionalBlanks, a.Dot, optionalBlanks)
|
||||||
|
|
||||||
// After a value, the line must end. There can be an optional comment.
|
|
||||||
endOfLineAfterValue = c.Seq(dropBlanks, a.EndOfLine.Or(comment))
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (t *parser) startKeyValuePair(p *parse.API) {
|
func (t *parser) startKeyValuePair(p *parse.API) {
|
||||||
|
@ -44,7 +41,7 @@ func (t *parser) startKeyValuePair(p *parse.API) {
|
||||||
err := t.SetKeyValuePair(key, value)
|
err := t.SetKeyValuePair(key, value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.Error("%s", err)
|
p.Error("%s", err)
|
||||||
} else if !p.Accept(endOfLineAfterValue) {
|
} else if !p.Accept(endOfLineOrComment) {
|
||||||
p.Expected("end of line")
|
p.Expected("end of line")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ var (
|
||||||
blank = a.Runes('\t', ' ')
|
blank = a.Runes('\t', ' ')
|
||||||
blanks = c.OneOrMore(blank)
|
blanks = c.OneOrMore(blank)
|
||||||
optionalBlanks = c.ZeroOrMore(blank)
|
optionalBlanks = c.ZeroOrMore(blank)
|
||||||
dropBlanks = m.Drop(optionalBlanks)
|
|
||||||
|
|
||||||
// Newline means LF (0x0A) or CRLF (0x0D0A).
|
// Newline means LF (0x0A) or CRLF (0x0D0A).
|
||||||
// This matches the default newline as defined by parsekit.
|
// This matches the default newline as defined by parsekit.
|
||||||
|
@ -25,15 +24,15 @@ var (
|
||||||
// Whitespace is defined as blanks + newlines.
|
// Whitespace is defined as blanks + newlines.
|
||||||
whitespace = c.OneOrMore(blank.Or(newline))
|
whitespace = c.OneOrMore(blank.Or(newline))
|
||||||
optionalWhitespace = c.ZeroOrMore(blank.Or(newline))
|
optionalWhitespace = c.ZeroOrMore(blank.Or(newline))
|
||||||
dropWhitespace = m.Drop(optionalWhitespace)
|
|
||||||
|
|
||||||
// A '#' hash symbol marks the rest of the line as a comment.
|
// A '#' hash symbol marks the rest of the line as a comment.
|
||||||
// All characters up to the end of the line are included in the comment.
|
// All characters up to the end of the line are included in the comment.
|
||||||
comment = c.Seq(a.Hash, c.ZeroOrMore(c.Not(a.EndOfLine)), m.Drop(a.EndOfLine))
|
comment = c.Seq(a.Hash, c.ZeroOrMore(c.Not(a.EndOfLine)))
|
||||||
|
optionalComment = c.Optional(comment)
|
||||||
|
|
||||||
endOfLineOrComment = optionalBlanks.Then(a.EndOfLine.Or(comment))
|
endOfLineOrComment = c.Seq(optionalBlanks, optionalComment, a.EndOfLine)
|
||||||
whitespaceOrComment = c.OneOrMore(c.Any(blank, newline, comment))
|
whitespaceOrComment = whitespace.Or(comment)
|
||||||
optionalWhitespaceOrComment = c.Optional(whitespaceOrComment)
|
optionalWhitespaceOrComment = c.ZeroOrMore(whitespaceOrComment)
|
||||||
)
|
)
|
||||||
|
|
||||||
// parser embeds the TOML ast.Document, so it can be extended with methods
|
// parser embeds the TOML ast.Document, so it can be extended with methods
|
||||||
|
|
|
@ -33,7 +33,7 @@ import (
|
||||||
var (
|
var (
|
||||||
arrayOpen = a.SquareOpen.Then(optionalWhitespaceOrComment)
|
arrayOpen = a.SquareOpen.Then(optionalWhitespaceOrComment)
|
||||||
arraySeparator = c.Seq(optionalWhitespaceOrComment, a.Comma, optionalWhitespaceOrComment)
|
arraySeparator = c.Seq(optionalWhitespaceOrComment, a.Comma, optionalWhitespaceOrComment)
|
||||||
arrayClose = c.Seq(c.Optional(optionalWhitespaceOrComment.Then(a.Comma)), optionalWhitespaceOrComment, a.SquareClose)
|
arrayClose = c.Seq(optionalWhitespaceOrComment, a.Comma.Optional(), optionalWhitespaceOrComment, a.SquareClose)
|
||||||
)
|
)
|
||||||
|
|
||||||
func (t *parser) parseArray(p *parse.API) (*ast.Value, bool) {
|
func (t *parser) parseArray(p *parse.API) (*ast.Value, bool) {
|
||||||
|
|
|
@ -5,8 +5,8 @@ import (
|
||||||
"git.makaay.nl/mauricem/go-toml/ast"
|
"git.makaay.nl/mauricem/go-toml/ast"
|
||||||
)
|
)
|
||||||
|
|
||||||
var falseValue = ast.NewValue(ast.TypeBoolean, false)
|
var falseValue = ast.NewValue(ast.TypeBool, false)
|
||||||
var trueValue = ast.NewValue(ast.TypeBoolean, true)
|
var trueValue = ast.NewValue(ast.TypeBool, true)
|
||||||
|
|
||||||
// Booleans are just the tokens you're used to. Always lowercase.
|
// Booleans are just the tokens you're used to. Always lowercase.
|
||||||
func (t *parser) parseBoolean(p *parse.API) (*ast.Value, bool) {
|
func (t *parser) parseBoolean(p *parse.API) (*ast.Value, bool) {
|
||||||
|
|
|
@ -40,11 +40,11 @@ var (
|
||||||
// "line ending backslash". When the last non-whitespace character on a line is
|
// "line ending backslash". When the last non-whitespace character on a line is
|
||||||
// a \, it will be trimmed along with all whitespace (including newlines) up to
|
// a \, it will be trimmed along with all whitespace (including newlines) up to
|
||||||
// the next non-whitespace character or closing delimiter.
|
// the next non-whitespace character or closing delimiter.
|
||||||
lineEndingBackslash = a.Backslash.Then(dropBlanks).Then(newline).Then(dropWhitespace)
|
lineEndingBackslash = c.Seq(a.Backslash, optionalBlanks, newline, optionalWhitespace)
|
||||||
)
|
)
|
||||||
|
|
||||||
// There are four ways to express strings: basic, multi-line basic, literal and
|
// There are four ways to express strings: basic, multi-line basic, literal and
|
||||||
// multi-line literal. All strings must contain only valid UTF-8 characters.
|
// multi-line literal. All strings must parse/value_array.gocontain only valid UTF-8 characters.
|
||||||
func (t *parser) parseString(p *parse.API) (*ast.Value, bool) {
|
func (t *parser) parseString(p *parse.API) (*ast.Value, bool) {
|
||||||
var value string
|
var value string
|
||||||
var ok bool
|
var ok bool
|
||||||
|
@ -89,13 +89,8 @@ func (t *parser) parseBasicString(name string, p *parse.API) (string, bool) {
|
||||||
p.Error("invalid character in %s: %q (must be escaped)", name, p.Result().Rune(0))
|
p.Error("invalid character in %s: %q (must be escaped)", name, p.Result().Rune(0))
|
||||||
return sb.String(), false
|
return sb.String(), false
|
||||||
case p.Accept(tok.StrInterpreted(nil, validEscape)):
|
case p.Accept(tok.StrInterpreted(nil, validEscape)):
|
||||||
s := p.Result().Value(0).(string)
|
if !appendStrInterpreted(p, sb) {
|
||||||
for _, r := range s {
|
return sb.String(), false
|
||||||
if r == utf8.RuneError {
|
|
||||||
p.Error("invalid UTF8 rune")
|
|
||||||
return sb.String(), false
|
|
||||||
}
|
|
||||||
sb.WriteRune(r)
|
|
||||||
}
|
}
|
||||||
case p.Peek(a.Backslash):
|
case p.Peek(a.Backslash):
|
||||||
p.Error("invalid escape sequence")
|
p.Error("invalid escape sequence")
|
||||||
|
@ -185,13 +180,8 @@ func (t *parser) parseMultiLineBasicString(p *parse.API) (string, bool) {
|
||||||
p.Error("invalid character in multi-line basic string: %q (must be escaped)", p.Result().Rune(0))
|
p.Error("invalid character in multi-line basic string: %q (must be escaped)", p.Result().Rune(0))
|
||||||
return sb.String(), false
|
return sb.String(), false
|
||||||
case p.Accept(tok.StrInterpreted(nil, c.OneOrMore(validEscape))):
|
case p.Accept(tok.StrInterpreted(nil, c.OneOrMore(validEscape))):
|
||||||
s := p.Result().Value(0).(string)
|
if !appendStrInterpreted(p, sb) {
|
||||||
for _, r := range s {
|
return sb.String(), false
|
||||||
if r == utf8.RuneError {
|
|
||||||
p.Error("invalid UTF8 rune")
|
|
||||||
return sb.String(), false
|
|
||||||
}
|
|
||||||
sb.WriteRune(r)
|
|
||||||
}
|
}
|
||||||
case p.Accept(lineEndingBackslash):
|
case p.Accept(lineEndingBackslash):
|
||||||
// NOOP, the line-ending backslash sequence is skipped.
|
// NOOP, the line-ending backslash sequence is skipped.
|
||||||
|
@ -212,6 +202,18 @@ func (t *parser) parseMultiLineBasicString(p *parse.API) (string, bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func appendStrInterpreted(p *parse.API, sb *strings.Builder) bool {
|
||||||
|
s := p.Result().Value(0).(string)
|
||||||
|
for _, r := range s {
|
||||||
|
if r == utf8.RuneError {
|
||||||
|
p.Error("invalid UTF8 rune")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
sb.WriteRune(r)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// Specific handling of input for multi-line literal strings.
|
// Specific handling of input for multi-line literal strings.
|
||||||
//
|
//
|
||||||
// • Multi-line literal strings are surrounded by three single quotes on
|
// • Multi-line literal strings are surrounded by three single quotes on
|
||||||
|
|
|
@ -7,17 +7,17 @@ import (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// Opener and closer for [table].
|
// Opener and closer for [table].
|
||||||
tableOpen = c.Seq(dropBlanks, a.SquareOpen, dropBlanks)
|
tableOpen = c.Seq(optionalBlanks, a.SquareOpen, optionalBlanks)
|
||||||
tableClose = c.Seq(dropBlanks, a.SquareClose, dropBlanks)
|
tableClose = c.Seq(optionalBlanks, a.SquareClose, optionalBlanks)
|
||||||
|
|
||||||
// Opener and closer for [[array.of.tables]].
|
// Opener and closer for [[array.of.tables]].
|
||||||
tableArrayOpen = c.Seq(dropBlanks, a.SquareOpen, a.SquareOpen, dropBlanks)
|
tableArrayOpen = c.Seq(optionalBlanks, a.SquareOpen, a.SquareOpen, optionalBlanks)
|
||||||
tableArrayClose = c.Seq(dropBlanks, a.SquareClose, a.SquareClose, dropBlanks)
|
tableArrayClose = c.Seq(optionalBlanks, a.SquareClose, a.SquareClose, optionalBlanks)
|
||||||
|
|
||||||
// Opener, separator and closer for { inline: "tables" }.
|
// Opener, separator and closer for { inline: "tables" }.
|
||||||
inlineTableOpen = c.Seq(dropBlanks, a.CurlyOpen, dropBlanks)
|
inlineTableOpen = c.Seq(optionalBlanks, a.CurlyOpen, optionalBlanks)
|
||||||
inlineTableSeparator = c.Seq(dropBlanks, a.Comma, dropBlanks)
|
inlineTableSeparator = c.Seq(optionalBlanks, a.Comma, optionalBlanks)
|
||||||
inlineTableClose = c.Seq(dropBlanks, a.CurlyClose, dropBlanks)
|
inlineTableClose = c.Seq(optionalBlanks, a.CurlyClose, optionalBlanks)
|
||||||
)
|
)
|
||||||
|
|
||||||
func (t *parser) startTable(p *parse.API) {
|
func (t *parser) startTable(p *parse.API) {
|
||||||
|
|
Loading…
Reference in New Issue