unstable

package
v2.2.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 17, 2024 License: MIT Imports: 6 Imported by: 12

Documentation

Overview

Package unstable provides APIs that do not meet the backward compatibility guarantees yet.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewParserError

func NewParserError(highlight []byte, format string, args ...interface{}) error

NewParserError is a convenience function to create a ParserError

Warning: Highlight needs to be a subslice of Parser.data, so only slices returned by Parser.Raw are valid candidates.

Types

type Iterator

type Iterator struct {
	// contains filtered or unexported fields
}

Iterator over a sequence of nodes.

Starts uninitialized, you need to call Next() first.

For example:

it := n.Children()
for it.Next() {
	n := it.Node()
	// do something with n
}

func (*Iterator) IsLast

func (c *Iterator) IsLast() bool

IsLast returns true if the current node of the iterator is the last one. Subsequent calls to Next() will return false.

func (*Iterator) Next

func (c *Iterator) Next() bool

Next moves the iterator forward and returns true if points to a node, false otherwise.

func (*Iterator) Node

func (c *Iterator) Node() *Node

Node returns a pointer to the node pointed at by the iterator.

type Kind

type Kind int

Kind represents the type of TOML structure contained in a given Node.

const (
	// Meta
	Invalid Kind = iota
	Comment
	Key

	// Top level structures
	Table
	ArrayTable
	KeyValue

	// Containers values
	Array
	InlineTable

	// Values
	String
	Bool
	Float
	Integer
	LocalDate
	LocalTime
	LocalDateTime
	DateTime
)

func (Kind) String

func (k Kind) String() string

String implementation of fmt.Stringer.

type Node

type Node struct {
	Kind Kind
	Raw  Range  // Raw bytes from the input.
	Data []byte // Node value (either allocated or referencing the input).
	// contains filtered or unexported fields
}

Node in a TOML expression AST.

Depending on Kind, its sequence of children should be interpreted differently.

  • Array have one child per element in the array.
  • InlineTable have one child per key-value in the table (each of kind InlineTable).
  • KeyValue have at least two children. The first one is the value. The rest make a potentially dotted key.
  • Table and ArrayTable's children represent a dotted key (same as KeyValue, but without the first node being the value).

When relevant, Raw describes the range of bytes this node is referring to in the input document. Use Parser.Raw() to retrieve the actual bytes.

func (*Node) Child

func (n *Node) Child() *Node

Child returns a pointer to the first child node of this node. Other children can be accessed calling Next on the first child. Returns an nil if this Node has no child.

func (*Node) Children

func (n *Node) Children() Iterator

Children returns an iterator over a node's children.

func (*Node) Key

func (n *Node) Key() Iterator

Key returns the children nodes making the Key on a supported node. Panics otherwise. They are guaranteed to be all be of the Kind Key. A simple key would return just one element.

func (*Node) Next

func (n *Node) Next() *Node

Next returns a pointer to the next node, or nil if there is no next node.

func (*Node) Valid

func (n *Node) Valid() bool

Valid returns true if the node's kind is set (not to Invalid).

func (*Node) Value

func (n *Node) Value() *Node

Value returns a pointer to the value node of a KeyValue. Guaranteed to be non-nil. Panics if not called on a KeyValue node, or if the Children are malformed.

type Parser

type Parser struct {
	KeepComments bool
	// contains filtered or unexported fields
}

Parser scans over a TOML-encoded document and generates an iterative AST.

To prime the Parser, first reset it with the contents of a TOML document. Then, process all top-level expressions sequentially. See Example.

Don't forget to check Error() after you're done parsing.

Each top-level expression needs to be fully processed before calling NextExpression() again. Otherwise, calls to various Node methods may panic if the parser has moved on the next expression.

For performance reasons, go-toml doesn't make a copy of the input bytes to the parser. Make sure to copy all the bytes you need to outlive the slice given to the parser.

Example
doc := `
	hello = "world"
	value = 42
	`
p := Parser{}
p.Reset([]byte(doc))
for p.NextExpression() {
	e := p.Expression()
	fmt.Printf("Expression: %s\n", e.Kind)
	value := e.Value()
	it := e.Key()
	k := it.Node() // shortcut: we know there is no dotted key in the example
	fmt.Printf("%s -> (%s) %s\n", k.Data, value.Kind, value.Data)
}
Output:

Expression: KeyValue
hello -> (String) world
Expression: KeyValue
value -> (Integer) 42
Example (Comments)

This example demonstrates how to parse a TOML document and preserving comments. Comments are stored in the AST as Comment nodes. This example displays the structure of the full AST generated by the parser using the following structure:

  1. Each root-level expression is separated by three dashes.
  2. Bytes associated to a node are displayed in square brackets.
  3. Siblings have the same indentation.
  4. Children of a node are indented one level.
doc := `# Top of the document comment.
# Optional, any amount of lines.

# Above table.
[table] # Next to table.
# Above simple value.
key = "value" # Next to simple value.
# Below simple value.

# Some comment alone.

# Multiple comments, on multiple lines.

# Above inline table.
name = { first = "Tom", last = "Preston-Werner" } # Next to inline table.
# Below inline table.

# Above array.
array = [ 1, 2, 3 ] # Next to one-line array.
# Below array.

# Above multi-line array.
key5 = [ # Next to start of inline array.
  # Second line before array content.
  1, # Next to first element.
  # After first element.
  # Before second element.
  2,
  3, # Next to last element
  # After last element.
] # Next to end of array.
# Below multi-line array.

# Before array table.
[[products]] # Next to array table.
# After array table.
`

var printGeneric func(*Parser, int, *Node)
printGeneric = func(p *Parser, indent int, e *Node) {
	if e == nil {
		return
	}
	s := p.Shape(e.Raw)
	x := fmt.Sprintf("%d:%d->%d:%d (%d->%d)", s.Start.Line, s.Start.Column, s.End.Line, s.End.Column, s.Start.Offset, s.End.Offset)
	fmt.Printf("%-25s | %s%s [%s]\n", x, strings.Repeat("  ", indent), e.Kind, e.Data)
	printGeneric(p, indent+1, e.Child())
	printGeneric(p, indent, e.Next())
}

printTree := func(p *Parser) {
	for p.NextExpression() {
		e := p.Expression()
		fmt.Println("---")
		printGeneric(p, 0, e)
	}
	if err := p.Error(); err != nil {
		panic(err)
	}
}

p := &Parser{
	KeepComments: true,
}
p.Reset([]byte(doc))
printTree(p)
Output:

---
1:1->1:31 (0->30)         | Comment [# Top of the document comment.]
---
2:1->2:33 (31->63)        | Comment [# Optional, any amount of lines.]
---
4:1->4:15 (65->79)        | Comment [# Above table.]
---
1:1->1:1 (0->0)           | Table []
5:2->5:7 (81->86)         |   Key [table]
5:9->5:25 (88->104)       | Comment [# Next to table.]
---
6:1->6:22 (105->126)      | Comment [# Above simple value.]
---
1:1->1:1 (0->0)           | KeyValue []
7:7->7:14 (133->140)      |   String [value]
7:1->7:4 (127->130)       |   Key [key]
7:15->7:38 (141->164)     | Comment [# Next to simple value.]
---
8:1->8:22 (165->186)      | Comment [# Below simple value.]
---
10:1->10:22 (188->209)    | Comment [# Some comment alone.]
---
12:1->12:40 (211->250)    | Comment [# Multiple comments, on multiple lines.]
---
14:1->14:22 (252->273)    | Comment [# Above inline table.]
---
1:1->1:1 (0->0)           | KeyValue []
15:8->15:9 (281->282)     |   InlineTable []
1:1->1:1 (0->0)           |     KeyValue []
15:18->15:23 (291->296)   |       String [Tom]
15:10->15:15 (283->288)   |       Key [first]
1:1->1:1 (0->0)           |     KeyValue []
15:32->15:48 (305->321)   |       String [Preston-Werner]
15:25->15:29 (298->302)   |       Key [last]
15:1->15:5 (274->278)     |   Key [name]
15:51->15:74 (324->347)   | Comment [# Next to inline table.]
---
16:1->16:22 (348->369)    | Comment [# Below inline table.]
---
18:1->18:15 (371->385)    | Comment [# Above array.]
---
1:1->1:1 (0->0)           | KeyValue []
1:1->1:1 (0->0)           |   Array []
19:11->19:12 (396->397)   |     Integer [1]
19:14->19:15 (399->400)   |     Integer [2]
19:17->19:18 (402->403)   |     Integer [3]
19:1->19:6 (386->391)     |   Key [array]
19:21->19:46 (406->431)   | Comment [# Next to one-line array.]
---
20:1->20:15 (432->446)    | Comment [# Below array.]
---
22:1->22:26 (448->473)    | Comment [# Above multi-line array.]
---
1:1->1:1 (0->0)           | KeyValue []
1:1->1:1 (0->0)           |   Array []
23:10->23:42 (483->515)   |     Comment [# Next to start of inline array.]
24:3->24:38 (518->553)    |       Comment [# Second line before array content.]
25:3->25:4 (556->557)     |     Integer [1]
25:6->25:30 (559->583)    |     Comment [# Next to first element.]
26:3->26:25 (586->608)    |       Comment [# After first element.]
27:3->27:27 (611->635)    |       Comment [# Before second element.]
28:3->28:4 (638->639)     |     Integer [2]
29:3->29:4 (643->644)     |     Integer [3]
29:6->29:28 (646->668)    |     Comment [# Next to last element]
30:3->30:24 (671->692)    |       Comment [# After last element.]
23:1->23:5 (474->478)     |   Key [key5]
31:3->31:26 (695->718)    | Comment [# Next to end of array.]
---
32:1->32:26 (719->744)    | Comment [# Below multi-line array.]
---
34:1->34:22 (746->767)    | Comment [# Before array table.]
---
1:1->1:1 (0->0)           | ArrayTable []
35:3->35:11 (770->778)    |   Key [products]
35:14->35:36 (781->803)   | Comment [# Next to array table.]
---
36:1->36:21 (804->824)    | Comment [# After array table.]

func (*Parser) Data

func (p *Parser) Data() []byte

Data returns the slice provided to the last call to Reset.

func (*Parser) Error

func (p *Parser) Error() error

Error returns any error that has occurred during parsing.

func (*Parser) Expression

func (p *Parser) Expression() *Node

Expression returns a pointer to the node representing the last successfully parsed expression.

func (*Parser) NextExpression

func (p *Parser) NextExpression() bool

NextExpression parses the next top-level expression. If an expression was successfully parsed, it returns true. If the parser is at the end of the document or an error occurred, it returns false.

Retrieve the parsed expression with Expression().

func (*Parser) Range

func (p *Parser) Range(b []byte) Range

Range returns a range description that corresponds to a given slice of the input. If the argument is not a subslice of the parser input, this function panics.

func (*Parser) Raw

func (p *Parser) Raw(raw Range) []byte

Raw returns the slice corresponding to the bytes in the given range.

func (*Parser) Reset

func (p *Parser) Reset(b []byte)

Reset brings the parser to its initial state for a given input. It wipes an reuses internal storage to reduce allocation.

func (*Parser) Shape added in v2.0.8

func (p *Parser) Shape(r Range) Shape

Shape returns the shape of the given range in the input. Will panic if the range is not a subslice of the input.

type ParserError

type ParserError struct {
	Highlight []byte
	Message   string
	Key       []string // optional
}

ParserError describes an error relative to the content of the document.

It cannot outlive the instance of Parser it refers to, and may cause panics if the parser is reset.

func (*ParserError) Error

func (e *ParserError) Error() string

Error is the implementation of the error interface.

type Position added in v2.0.8

type Position struct {
	// Number of bytes from the beginning of the input.
	Offset int
	// Line number, starting at 1.
	Line int
	// Column number, starting at 1.
	Column int
}

Position describes a position in the input.

type Range

type Range struct {
	Offset uint32
	Length uint32
}

Range of bytes in the document.

type Shape added in v2.0.8

type Shape struct {
	Start Position
	End   Position
}

Shape describes the position of a range in the input.

type Unmarshaler added in v2.2.0

type Unmarshaler interface {
	UnmarshalTOML(value *Node) error
}

The Unmarshaler interface may be implemented by types to customize their behavior when being unmarshaled from a TOML document.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL