File: fftoml.go

package info (click to toggle)
golang-github-peterbourgon-ff 3.4.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 408 kB
  • sloc: sh: 9; makefile: 4
file content (85 lines) | stat: -rw-r--r-- 2,466 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// Package fftoml provides a TOML config file paser.
package fftoml

import (
	"fmt"
	"io"

	"github.com/pelletier/go-toml"
	"github.com/peterbourgon/ff/v3/internal"
)

// Parser is a parser for TOML file format. Flags and their values are read
// from the key/value pairs defined in the config file.
func Parser(r io.Reader, set func(name, value string) error) error {
	return New().Parse(r, set)
}

// ConfigFileParser is a parser for the TOML file format. Flags and their values
// are read from the key/value pairs defined in the config file.
// Nested tables and keys are concatenated with a delimiter to derive the
// relevant flag name.
type ConfigFileParser struct {
	delimiter string
}

// New constructs and configures a ConfigFileParser using the provided options.
func New(opts ...Option) (c ConfigFileParser) {
	c.delimiter = "."
	for _, opt := range opts {
		opt(&c)
	}
	return c
}

// Parse parses the provided io.Reader as a TOML file and uses the provided set function
// to set flag names derived from the tables names and their key/value pairs.
func (c ConfigFileParser) Parse(r io.Reader, set func(name, value string) error) error {
	var m map[string]any
	if err := toml.NewDecoder(r).Decode(&m); err != nil {
		return ParseError{Inner: err}
	}

	if err := internal.TraverseMap(m, c.delimiter, set); err != nil {
		return ParseError{Inner: err}
	}

	return nil
}

// Option is a function which changes the behavior of the TOML config file parser.
type Option func(*ConfigFileParser)

// WithTableDelimiter is an option which configures a delimiter
// used to prefix table names onto keys when constructing
// their associated flag name.
// The default delimiter is "."
//
// For example, given the following TOML
//
//	[section.subsection]
//	value = 10
//
// Parse will match to a flag with the name `-section.subsection.value` by default.
// If the delimiter is "-", Parse will match to `-section-subsection-value` instead.
func WithTableDelimiter(d string) Option {
	return func(c *ConfigFileParser) {
		c.delimiter = d
	}
}

// ParseError wraps all errors originating from the TOML parser.
type ParseError struct {
	Inner error
}

// Error implenents the error interface.
func (e ParseError) Error() string {
	return fmt.Sprintf("error parsing TOML config: %v", e.Inner)
}

// Unwrap implements the errors.Wrapper interface, allowing errors.Is and
// errors.As to work with ParseErrors.
func (e ParseError) Unwrap() error {
	return e.Inner
}