TOML parser for Golang with reflection.

Related tags

Text Processing toml
Overview

THIS PROJECT IS UNMAINTAINED

The last commit to this repo before writing this message occurred over two years ago. While it was never my intention to abandon this package, it's clear that I have.

While many issues and PRs have piled up, the most significant short-coming of this library at present is that it has fallen behind the upstream TOML specification.

Many folks are still using this package, and so long as you're happy, there's no pressing reason to switch to something else. With that said, it would probably be wise to organize around an existing alternative or fork this project and update it.

I have no plans on handing ownership of this project over to someone else, unless that someone can meet an extremely high bar that inspires confidence that the project will be in good hands. In particular, I've had mostly poor (but not always) experiences with handing maintenance of a project over to someone else.

TOML parser and encoder for Go with reflection

TOML stands for Tom's Obvious, Minimal Language. This Go package provides a reflection interface similar to Go's standard library json and xml packages. This package also supports the encoding.TextUnmarshaler and encoding.TextMarshaler interfaces so that you can define custom data representations. (There is an example of this below.)

Spec: https://github.com/toml-lang/toml

Compatible with TOML version v0.4.0

Documentation: https://godoc.org/github.com/BurntSushi/toml

Installation:

go get github.com/BurntSushi/toml

Try the toml validator:

go get github.com/BurntSushi/toml/cmd/tomlv
tomlv some-toml-file.toml

Build Status GoDoc

Testing

This package passes all tests in toml-test for both the decoder and the encoder.

Examples

This package works similarly to how the Go standard library handles XML and JSON. Namely, data is loaded into Go values via reflection.

For the simplest example, consider some TOML file as just a list of keys and values:

Age = 25
Cats = [ "Cauchy", "Plato" ]
Pi = 3.14
Perfection = [ 6, 28, 496, 8128 ]
DOB = 1987-07-05T05:45:00Z

Which could be defined in Go as:

type Config struct {
  Age int
  Cats []string
  Pi float64
  Perfection []int
  DOB time.Time // requires `import time`
}

And then decoded with:

var conf Config
if _, err := toml.Decode(tomlData, &conf); err != nil {
  // handle error
}

You can also use struct tags if your struct field name doesn't map to a TOML key value directly:

some_key_NAME = "wat"
type TOML struct {
  ObscureKey string `toml:"some_key_NAME"`
}

Using the encoding.TextUnmarshaler interface

Here's an example that automatically parses duration strings into time.Duration values:

[[song]]
name = "Thunder Road"
duration = "4m49s"

[[song]]
name = "Stairway to Heaven"
duration = "8m03s"

Which can be decoded with:

type song struct {
  Name     string
  Duration duration
}
type songs struct {
  Song []song
}
var favorites songs
if _, err := toml.Decode(blob, &favorites); err != nil {
  log.Fatal(err)
}

for _, s := range favorites.Song {
  fmt.Printf("%s (%s)\n", s.Name, s.Duration)
}

And you'll also need a duration type that satisfies the encoding.TextUnmarshaler interface:

type duration struct {
	time.Duration
}

func (d *duration) UnmarshalText(text []byte) error {
	var err error
	d.Duration, err = time.ParseDuration(string(text))
	return err
}

More complex usage

Here's an example of how to load the example from the official spec page:

# This is a TOML document. Boom.

title = "TOML Example"

[owner]
name = "Tom Preston-Werner"
organization = "GitHub"
bio = "GitHub Cofounder & CEO\nLikes tater tots and beer."
dob = 1979-05-27T07:32:00Z # First class dates? Why not?

[database]
server = "192.168.1.1"
ports = [ 8001, 8001, 8002 ]
connection_max = 5000
enabled = true

[servers]

  # You can indent as you please. Tabs or spaces. TOML don't care.
  [servers.alpha]
  ip = "10.0.0.1"
  dc = "eqdc10"

  [servers.beta]
  ip = "10.0.0.2"
  dc = "eqdc10"

[clients]
data = [ ["gamma", "delta"], [1, 2] ] # just an update to make sure parsers support it

# Line breaks are OK when inside arrays
hosts = [
  "alpha",
  "omega"
]

And the corresponding Go types are:

type tomlConfig struct {
	Title string
	Owner ownerInfo
	DB database `toml:"database"`
	Servers map[string]server
	Clients clients
}

type ownerInfo struct {
	Name string
	Org string `toml:"organization"`
	Bio string
	DOB time.Time
}

type database struct {
	Server string
	Ports []int
	ConnMax int `toml:"connection_max"`
	Enabled bool
}

type server struct {
	IP string
	DC string
}

type clients struct {
	Data [][]interface{}
	Hosts []string
}

Note that a case insensitive match will be tried if an exact match can't be found.

A working example of the above can be found in _examples/example.{go,toml}.

Issues
  • Inline Table Support

    Inline Table Support

    Hey, forgive me if I missed this. Recently, inline tables made it into the spec, is this on the roadmap for being supported in this package soon (meaning what kind of priority would supporting inline tables be, if it's one at all)? Just wondering! Also, awesome library!

    opened by ttacon 21
  • Encoder [WIP]

    Encoder [WIP]

    Work-in-progress improvements to the encoder. I'm trying to get it to be fully functioning and would appreciate help and/or code reviews.

    TODOs:

    • [x] Array of tables
    • [ ] Nested arrays of tables
    opened by sqs 15
  • Cannot decode integer value to float64 type.

    Cannot decode integer value to float64 type.

    It seems like a struct containing a float64 field cannot be decoded from a TOML document containing an integer value. The following example demonstrates this.

    package main
    
    import (
        "log"
    
        "github.com/BurntSushi/toml"
    )
    
    func main() {
        raw := "Foo = 123"
        var s struct {
            Foo float64
        }
        _, err := toml.Decode(raw, &s)
        if err != nil {
            log.Fatal(err)
        }
        log.Print(s)
    }
    

    The error message printed looks like this

    2014/09/09 13:42:51 Type mismatch for 'struct { Foo float64 }.Foo': Expected float but found 'int64'.

    opened by bmatsuo 14
  • Using a TextUnmarshaler in a map value doesn't work

    Using a TextUnmarshaler in a map value doesn't work

    Could you explain how to apply this

    func (d *duration) UnmarshalText(text []byte) (err error) {
    	d.Duration, err = time.ParseDuration(string(text))
    	return err
    }
    

    to

    type httpclient struct {
        Timeouts map[string]string
    }
    

    to be able to write in the config like this

    [httpclient.timeouts]
    client = "60s"
    2XX = "50ms"
    3XX = "1000ms"
    4XX = "2000ms"
    5XX = "5000ms"
    

    ?

    bug 
    opened by GarryGaller 12
  • add Marshaler interface

    add Marshaler interface

    Hi @BurntSushi, I've noticed that there is no nice way to handle Marshal/Encode operation unless implementing encoding.TextMarshaler interface, which can't be used if struct should be also marshalable to JSON (json libraries also looks for encoding.TextMarshaler),

    so I've added Marshaler interface with following signature:

    type Marshaler interface {
        MarshalTOML() ([]byte, error)
    }
    

    Also I've added various tests for this feautre.

    opened by kovetskiy 12
  • Add

    Add "extended errors"

    The lexer and parser now always return a ParseError; the Error() method is mostly unchanged:

    toml: line 1 (last key "x.key"): newlines not allowed within inline tables
    

    This adds an ErrorWithLocation() method, which will add some context where the error occurred, similar to e.g. clang or the Rust compiler:

    toml: error: newlines not allowed within inline tables
    
    At line 1, column 18:
    
          1 | x = [{ key = 42 #
    			   ^
    

    And the ErrorWithUsage() also adds some usage guidance (not always present):

    toml: error: newlines not allowed within inline tables
    
    At line 1, column 16:
    
          1 | x = [{ key = 42
    			 ^
    Error help:
    
    	Inline tables must always be on a single line:
    
    	    table = {key = 42, second = 43}
    
    	It is invalid to split them over multiple lines like so:
    
    	    # INVALID
    	    table = {
    		key    = 42,
    		second = 43
    	    }
    
    	Use regular for this:
    
    	    [table]
    	    key    = 42
    	    second = 43
    

    The line/column information should now also always be correct, and a number of error message have been tweaked a bit.

    Fixes #201 Fixes #217

    opened by arp242 11
  • Support for delayed parsing or unification of sections

    Support for delayed parsing or unification of sections

    I have some occasions there I might have a few sections of configuration that map to modules in a system that are not coupled with the top-level configuration loader. These sections could be considered to need somewhat dynamic unification.

    With JSON it's rather easy since one can simply put placeholders using json.RawMessage. Which allows those sections of the document to be delayed. Would you consider accepting something like a toml.RawSection or similar?

    In the meantime I've resorted to hardcoding these subsections but it's brittle and requires constant edits to ensure the compiled in packages that implement this special submodule interface are included properly in the configuration. I could also parse to a generic map and unify by hand but this results in a lot of ugly boilerplate code that has to repeated for each section type.

    opened by cararemixed 11
  • switch to MIT license

    switch to MIT license

    The WTFPL causes people to not want to use this library. Historically, I've been against changing the license mostly because it's just a pain to do so. Ideally, we'd like to get a sign off from all people that have made non-trivial contributions. (And if we can't, we either need to stop the re-licensing process or remove/rewrite those contributions. I'm not particularly inclined to the do latter, but if we can do the former, than we should.)

    So, this issue is going to track the relicensing progress. I'll start by listing some of the major contributors, where I interpreted "major" as "100 lines of code or more."

    • [x] @BurntSushi
    • [x] @cespare
    • [x] @sqs
    • [x] @rjeczalik
    • [x] @ttacon
    • [x] @bbuck
    • [x] @halostatue
    • [x] @sethwklein
    opened by BurntSushi 10
  • panic runtime error while unmarshal `bad-utf8-at-end.toml` on go 1.17

    panic runtime error while unmarshal `bad-utf8-at-end.toml` on go 1.17

    Hi! thanks a lot for this useful package!

    but we got a problem with BurntSushi/toml. There is a panic while unmarshal bad-utf8-at-end.toml from your tests on go 1.17.

    it seems that runtime.panic was changes: cmd/compile,runtime: provide index information on bounds check failure. and this check doesn't work now: https://github.com/BurntSushi/toml/blob/9be4ccf5153f55ef1032bdf52d01e65ea480380b/parse.go#L28

    For reproduce I wrote next sample:

    	b, _ := ioutil.ReadFile("bad-utf8-at-end.toml")
    	var v interface{}
    	if err := toml.Unmarshal(b, &v); err != nil {
    		log.Fatalf("toml.Unmarshal error: %v", err)
    	}
    

    Result:

    panic: runtime error: slice bounds out of range [238:237] [recovered]
            panic: runtime error: slice bounds out of range [238:237]
    
    goroutine 1 [running]:
    github.com/BurntSushi/toml.parse.func1()
            /home/home/go/pkg/mod/github.com/!burnt!sushi/[email protected]/parse.go:46 +0x16a
    panic({0x5072a0, 0xc000148018})
            /usr/local/go/src/runtime/panic.go:1047 +0x262
    github.com/BurntSushi/toml.(*lexer).current(0xc000150000)
            /home/home/go/pkg/mod/github.com/!burnt!sushi/[email protected]/lex.go:129 +0x90
    github.com/BurntSushi/toml.(*lexer).emit(0xc000150000, 0x6)
            /home/home/go/pkg/mod/github.com/!burnt!sushi/[email protected]/lex.go:133 +0x27
    github.com/BurntSushi/toml.lexMultilineString(0xc000150000)
            /home/home/go/pkg/mod/github.com/!burnt!sushi/[email protected]/lex.go:693 +0x2f1
    github.com/BurntSushi/toml.(*lexer).nextItem(0xc000150000)
            /home/home/go/pkg/mod/github.com/!burnt!sushi/[email protected]/lex.go:98 +0xf9
    github.com/BurntSushi/toml.(*parser).next(0xc0001401c0)
            /home/home/go/pkg/mod/github.com/!burnt!sushi/[email protected]/parse.go:95 +0x55
    github.com/BurntSushi/toml.(*parser).topLevel(0xc0001401c0, {0x12, {0xc00014c100, 0x0}, 0x5})
            /home/home/go/pkg/mod/github.com/!burnt!sushi/[email protected]/parse.go:172 +0x732
    github.com/BurntSushi/toml.parse({0xc00014c100, 0xf2})
            /home/home/go/pkg/mod/github.com/!burnt!sushi/[email protected]/parse.go:79 +0x4f5
    github.com/BurntSushi/toml.(*Decoder).Decode(0xc000116350, {0x4f7360, 0xc000116340})
            /home/home/go/pkg/mod/github.com/!burnt!sushi/[email protected]/decode.go:120 +0x625
    github.com/BurntSushi/toml.Decode({0xc00014c000, 0xf2}, {0x4f7360, 0xc000116340})
            /home/home/go/pkg/mod/github.com/!burnt!sushi/[email protected]/decode.go:135 +0x10f
    github.com/BurntSushi/toml.Unmarshal({0xc00014a000, 0xf2, 0x200}, {0x4f7360, 0xc000116340})
            /home/home/go/pkg/mod/github.com/!burnt!sushi/[email protected]/decode.go:23 +0x85
    main.main()
            /home/home/t/main.go:12 +0xe5
    

    upd: I can try to create a PR for fix it )

    bug 
    opened by afdesk 9
  • Fix override map element value during decode

    Fix override map element value during decode

    I have map, that has structures as elements.

    type LogConfig struct {
         Filename string  `toml:"file"`
         Level       string  `toml:"level"`
    }
    
    type Config struct {
        Loggers map[string]*LogConfig `toml:"log"`
    }
    
    fun NewConfig() *Config {
        return &Config{
             Loggers: map[string]*LogConfig {
                     "error": &LogConfig{Level: "error"},
                     "access": &LogConfig{Level: "info"},
            }
    }
    
    cfg := NewConfig()
    toml.DecodeFile("config.toml", &cfg)
    

    And If I do not specify the both "level and file" in config, I lose the defaults with I specify on creating Config.

    I expected that level will keep origin value if it is not specified in config.toml

    opened by bgaifullin 9
  • added support and tests for multiline string encoding closes BurntSushi/toml#64

    added support and tests for multiline string encoding closes BurntSushi/toml#64

    I would like to propose a solution to encoding multiline strings and raw multiline strings that I had raised in the issue BurntSushi/toml#64.

    The proposal is to accept a new struct tag modifier which can take values of "multiline_string" or "multiline_rawstring" (exported as constants MOD_MULTILINE_STRING and MOD_MULTILINE_RAWSTRING). On detecting presence of either of these modifiers, the type of the struct member is checked to confirm to reflect.String and then the Key.String() to which the modifier applies is inserted into a new map attribute of Encoder called modifiers.

    In the functions that actually process and emit the key/value (in this case in keyEqElement) we can check for presence of the key being processed currently in modifiers and if the modifier is MOD_MULTILINE_STRING or MOD_MULTILINE_RAWSTRING, the element is written by the new writeMultiLineString() function. The reason for choosing the route of using an additional encoder attribute is that Key is currently implemented as []string which makes it difficult to store modifiers with the Key itself.

    The same concept can be extended to any other output modifiers if necessary even in the future. I have added tests for multiline string encoding currently in the encode_test.go file (not yet figured out the toml-test package) and still need to writeup documentation but would like to seek review of the proposal

    opened by srinathh 9
  • Encoding: 'omitempty' will panic if the struct contains a uncomparable type

    Encoding: 'omitempty' will panic if the struct contains a uncomparable type

    While encoding a struct will be checked for emptiness with the isEmpty function:

    func isEmpty(rv reflect.Value) bool {
    	switch rv.Kind() {
    	case reflect.Array, reflect.Slice, reflect.Map, reflect.String:
    		return rv.Len() == 0
    	case reflect.Struct:
    		return reflect.Zero(rv.Type()).Interface() == rv.Interface()
    	case reflect.Bool:
    		return !rv.Bool()
    	}
    	return false
    }
    

    The comparing of structs panics if the structs contains any uncomparable type.

    Minimal example:

    type a struct {
    	B b `toml:"B,omitempty"`
    }
    
    type b struct {
    	C []string `toml:"C,omitempty"`
    }
    
    func TestToml(t *testing.T) {
    	b1 := b{C: []string{"foo"}}
    	a1 := a{B: b1}
    	var buf bytes.Buffer
    	toml.NewEncoder(&buf).Encode(a1)
    	fmt.Printf("%s", buf.String())
    }
    

    Output:

    === RUN   TestToml
    --- FAIL: TestToml (0.00s)
    panic: runtime error: comparing uncomparable type data.b [recovered]
    	panic: runtime error: comparing uncomparable type data.b [recovered]
    	panic: runtime error: comparing uncomparable type data.b
    
    opened by ybaldus 8
  • the unmarshal and decode API are wasteful and somewhat misleading

    the unmarshal and decode API are wasteful and somewhat misleading

    Hi, I was just looking at ways the unmarshalling and decoding is handled by this package. I must say im a bit terrifed with what I saw.

    So Unmarshalconverts bytes to string and passes it to Decode

    func Unmarshal(p []byte, v interface{}) error {
    	_, err := Decode(string(p), v)
    	return err
    }
    

    Then Decodeconverts the string to io.Reader and creates a new Decoder

    func Decode(data string, v interface{}) (MetaData, error) {
    	return NewDecoder(strings.NewReader(data)).Decode(v)
    }
    

    Finally, decoder.Decode, uses io.ReadAll to read everything into []bytes and converts it back into a string before calling parse.

    data, err := ioutil.ReadAll(dec.r)
    if err != nil {
    	return MetaData{}, err
    }
    p, err := parse(string(data))
    if err != nil {
    	return MetaData{}, err
    }
    

    So it seems like using the Unmarshal function is pretty wasteful since it does this coversion roudtrip.

    Additionally. it is not possible to use the decoder created by NewDecoder in a true decoder fashion, since usually it is read until EOF or another error. But EOF is never returned by decoder.Decode.

    So, the below will just hang. Although it is the expected way to use a decoder.

    for {
        if err := dec.Decode(&data); err == io.EOF {
            break
        } else if err != nil {
            panic(err)
        }
    }
    
    v2 
    opened by bluebrown 3
  • Support encoding comments and specifying the encoding format

    Support encoding comments and specifying the encoding format

    This allows encoding comments and setting some flags to control the format. While toml.Marshaler added in #327 gives full control over how you want to format something, I don't think it's especially user-friendly to tell everyone to create a new type with all the appropriate formatting, escaping, etc. The vast majority of of use cases probably just call in to a few simple categories such as "use """ or "encode this number as a hex".

    I grouped both features together as they're closely related: both set additional information on how to write keys.

    What I want is something that:

    1. allows setting attributes programmatically;
    2. supports round-tripping by default on a standard struct;
    3. plays well with other encoders/decoders;
    4. has a reasonable uncumbersome API.

    Most options (custom types, struct tags) fail at least one of these; there were some PRs for struct tags, but they fail at 1, 2, and (arguably) 4. Custom types fail at 2, 3, and probably 4.


    This adds SetMeta() to the Encoder type; this is already what we have when decoding, and all additional information will be set on it. On MetaData we add the following types:

    SetType()       Set TOML type info.
    TypeInfo()      Get TOML type info.
    Doc()           Set "doc comment" above the key.
    Comment()       Set "inline comment" after the key.
    

    Every TOML type has a type in this package, which support different formatting options (see type_toml.go):

    Bool
    String
    Int
    Float
    Datetime
    Table
    Array
    ArrayTable
    

    For example:

    meta := toml.NewMetaData().
            SetType("key", toml.Int{Width: 4, Base: 16}).
            Doc("key", "A codepoint").
    Comment("key", "ë")
    toml.NewEncoder(os.Stdout).SetMeta(meta).Encode(struct {
            Key string `toml:"key"`
    }{"ë")
    

    Would write:

    # A codepoint.
    key = 0x00eb  # ë
    

    It also has Key() to set both:

    toml.NewMetaData().
        Key("key", toml.Int{Width: 4, Base: 16}, toml.Doc("A codepoint"), toml.Comment("ë")).
        Key("other", toml.Comment("..."))
    

    The advantage of this is that it reduces the number of times you have to type the key string to 1, but it uses interface{}. Not yet decided which one I'll stick with, and also not a huge fan of Doc() and Comment(), but I can't really think of anything clearer at the moment (these are the names the Go ast uses).


    The Decode() sets all this information on the MetaData, so this:

    meta, _ := toml.Decode(..)
    toml.NewEncoder(os.Stdout).SetMeta(meta).Encode(..)
    

    Will write it out as "key = 0x00eb" again, rather than "key = 235".

    This way, pretty much any flag can be added programmatically without getting in the way of JSON/YAML/whatnot encoding/decoding.


    I don't especially care how you need to pass the keys as strings, but there isn't really any good way to do it otherwise. There is also the problem that the "key" as found in the parser may be different than the "key" the user is expecting if you don't use toml struct tags:

    type X struct { Key int }
    

    Will read "key = 2" in to "Key", but when encoding it will write as "Key" rather than "key". The type information will be set to "key", but when encoding it will look for "Key", so round-tripping won't work correct and has the potential for confusion if the wrong key is set.

    This is not so easy to fix since we don't have access to the struct in the parser. I think it's fine to just document this as a caveat and tell people to use struct tags, which is a good idea in any case.


    I'm not necessarily opposed to also adding struct tags for most of these things, although I'm not a huge fan of them. Since struct tags can't be set programmatically it's not really suitable for many use cases (e.g. setting comments dynamically, using multiline strings only if the string contains newlines, etc.) It's something that could maybe be added in a future PR, if a lot of people ask for it.

    Fixes #64 Fixes #75 Fixes #160 Fixes #192 Fixes #213 Fixes #269

    v2 
    opened by arp242 3
  • Require 2-digit hour for local time

    Require 2-digit hour for local time

    Given a=1:32:00, this package returns a valid time-local value instead of returning an error.

    Reproduction

    https://play.golang.org/p/fciY3UVyoT6

    toml.Unmarshal([]byte("a=1:32:00"), &v)
    

    Or using the toml-test decoder:

    $ echo "a=1:32:00" | toml-test-decoder2
    {
      "a": {
        "type": "time-local",
        "value": "01:32:00"
      }
    }
    
    bug 
    opened by moorereason 3
  • support round tripping with comments

    support round tripping with comments

    This is related to #75 but the solution might look quite different.

    TOML is being used for the dep tool, and a major obstacle to making that tool easier to use is the fact that the Gopkg.toml file cannot be programmatically manipulated without loss of user-edited content.

    If the toml package supported round-tripping the TOML while retaining comments, I believe that it would help a great deal.

    I'm afraid I'm sure how the API would look though. Some degree of loss is probably inevitable, but it may be possible to a job that's good enough for all practical cases.

    enhancement v2 
    opened by rogpeppe 2
  • proposal: allow unmarshaling into existing map value

    proposal: allow unmarshaling into existing map value

    I have map, that has structures as elements.

    type LogConfig struct {
         Filename string  `toml:"file"`
         Level       string  `toml:"level"`
    }
    
    type Config struct {
        Loggers map[string]*LogConfig `toml:"log"`
    }
    
    fun NewConfig() *Config {
        return &Config{
             Loggers: map[string]*LogConfig {
                     "error": &LogConfig{Level: "error"},
                     "access": &LogConfig{Level: "info"},
            }
    }
    
    cfg := NewConfig()
    toml.DecodeFile("config.toml", &cfg)
    

    And If I do not specify the both "level and file" in config, I lose the defaults with I specify on creating Config because tome.Decode always re-creates map items during decode.

    As user I expect that if some option is not specified in config, it will keep original value.

    PS: I agree that encoding/json has the similar behaviour, https://play.golang.org/p/d6t50gCppF but it is not useful for configs.

    I found the following workarounds:

    • use structure instead of map
    • re-init LogConfig after decode.

    but they are not convenient and makes code more complex.

    enhancement v2 
    opened by bgaifullin 1
Releases(v1.2.0)
  • v1.2.0(Jul 20, 2022)

    This release adds a few additional features:

    • Support encoding and decoding json.Number, making interoperability with JSON when using json.Encoder.UseNumber() easier.

    • Support time.Duration string format; an integer will be interpreted as nanoseconds (like before), but a string like "5h" will be parsed. On encoding the string format is used.

    • The omitempty struct tag now also works for structs with all zero values, for example an empty time.Time. A struct is considered "empty" when all fields (exported and private) are the zero value.

    • Allow using interface{} (or any) as the map key when decoding.

    And some fixes:

    • Fix encoding.TextUnmarshaler not working for map values.

    • Make encoding.TextUnmarshaler and toml.Unmarshaler work if MarshalText() or MarshalTOML() have a pointer receiver.

    • Error out on nil returns from MarshalTOML/MarshalText; before they would get encoded as invalid TOML (keyname =).

    • Fix a panic where it would try to encode array = [{}, 0] as:

      [[array]]
      [[array]]
      

      Which isn't valid as 0 isn't a table.

    • Some better error reporting for some errors.

    Source code(tar.gz)
    Source code(zip)
  • v1.1.0(Apr 4, 2022)

    Just a few bugfixes:

    • Skip fields with toml:"-" even when they're unsupported types. Previously something like this would fail to encode due to func being an unsupported type:

      struct {
          Str  string `toml:"str"
          Func func() `toml:"-"`
      }
      
    • Multiline strings can't end with \. This is valid:

      # Valid
      key = """ foo \
      """
      
      # Invalid
      key = """ foo \ """
      
    • Don't quote values in TOMLMarshaler. Previously they would always include quoting (e.g. "value"), while the entire point of this interface is to bypass that.

    Source code(tar.gz)
    Source code(zip)
  • v1.0.0(Jan 12, 2022)

    This release adds much more detailed errors, support for the toml.Marshaler interface, and several fixes.

    There is no special meaning in the jump to v1.0; the 0.x releases were always treated as if they're 1.x with regards to compatibility; the versioning scheme for this library predates the release of modules.

    New features

    • Error reporting is much improved; the reported position of errors should now always be correct and the library can print more detailed errors (#299, #332)

      Decode always return a toml.ParseError, which has three methods:

      • Error() behaves as before and shows a single concise line with the error.

      • ErrorWithPosition() shows the same error, but also shows the line the error occurred at, similar to e.g. clang or the Rust compiler.

      • ErrorWithUsage() is the same as ErrorWithPosition(), but may also show a longer usage guidance message. This isn't always present (in which case it behaves identical to ErrorWithPosition()), but it should be present for most common mistakes and sources of confusion.

      Which error the correct one to use is depends on your application and preferences; in general I would recommend using at least ErrorWithPosition() for user-facing errors, as it's much more helpful for users of any skill level. If your users are likely to be non-technical then ErrorWithUsage() is probably a good idea; I did my best to avoid technical jargon such as "newline" and phrase things in a way that's understandable by most people not intimately familiar with these sort of things.

      Additionally, the TOML key that fialed should now always be reported in all errors.

    • Add toml.Marshaler interface. This can be used if you want full control over how something is marshalled as TOML, similar to json.Marshaler etc. This takes precedence over encoding.TextMarshaler. (#327)

    • Allow TOML integers to be decoded to a Go float (#325)

      Previously int = 42 could only be decoded to an int* type; now this can also be decoded in a float type as long as it can be represented without loss of data.

    Fixes

    • Key.String() is now quoted when needed (#333)

    • Fix decoding of nested structs on 32bit platforms (#314)

    • Empty slices are now always []T{} rather than nil, which was the behaviour in v0.3.1 and before. While they are identical for most purposes, encoding/json encodes them different ([] vs. null), making it an (accidentally) incompatible change (#339)

    Source code(tar.gz)
    Source code(zip)
  • v0.4.1(Aug 5, 2021)

    This fixes a cyclic module dependency issue with github.com/BurntSushi/toml-test that prevented some people from updating. See #313 for some details.

    Source code(tar.gz)
    Source code(zip)
  • v0.4.0(Aug 2, 2021)

    After some time of inactivity this package is now maintained again.

    This release should support alll of TOML 1.0 and has various bugfixes and a few small improvements.

    This requires Go 1.13 or newer; older Go versions will no longer work.

    TOML 1.0 support

    Previously this library implemented TOML 0.3; now all of TOML 1.0 is supported:

    • Support dotted keys (a.b = 1, a = {b.c = 2}).

    • Mixed arrays: in previous TOML versions array values all had to be of the same type; you can now freely mix types, including inline tables.

    • Support hex (0x2f9a), binary (0b0110), and octal (0o777) literals, and support nan and inf for floats.

    • Support local datetimes, dates, and times. These are dates and times without a timezone and are parsed in the local timezone.

    • Allow accidental whitespace between backslash and newline in the line continuation operator in multi-line basic strings.

    There should be no incompatibilities as such; all existing valid TOML files should continue to work. However, the parser previously allowed the following invalid values:

    • It would allow literal control characters in strings.

    • It would allow leading zeroes in decimal ints and floats.

    Neither of these was ever valid TOML, and are explicitly forbidden by the specification. But the library erroneously permitted them.

    Other changes

    • Set up Go modules.

    • Allow escaping the \, and allow triple-quotes strings to end with a quote (e.g. x="""x"""").

    • All control characters inside strings are properly escaped when encoding.

    • Support encoding nested anonymous structs.

    • Encode toml.Primitive values.

    • You get a more helpful error on UTF-16 files (probably the most common non-UTF-8 compatible encoding). Also read over UTF-16 BOM in UTF-8 files.

    • Call MarshalText and UnmarshalText consistently on all types; before this didn't always happen in some cases.

    • Allow empty quoted keys ("" = 1); silly, but explicitly mentioned as valid.

    • Don't panic in encoder on unsupported types; return an error instead.

    • Don't panic on unclosed inline arrays.

    • Add Decoder and deprecate DecodeReader(); this is more consistent with how other decoders tend to work and allows adding decoding options.

    • Add DecodeFS() for Go 1.16 or newer.

    • Avoid creating new functions/allocations in lexSkip; small performance improvement.

    Source code(tar.gz)
    Source code(zip)
  • v0.1.0(Aug 29, 2014)

Owner
Andrew Gallant
I love to code.
Andrew Gallant
omniparser: a native Golang ETL streaming parser and transform library for CSV, JSON, XML, EDI, text, etc.

omniparser Omniparser is a native Golang ETL parser that ingests input data of various formats (CSV, txt, fixed length/width, XML, EDI/X12/EDIFACT, JS

JF Technology 482 Aug 1, 2022
User agent string parser in golang

User agent parsing useragent is a library written in golang to parse user agent strings. Usage First install the library with: go get xojoc.pw/userage

Alexandru Cojocaru 71 Aug 2, 2021
Freestyle xml parser with golang

fxml - FreeStyle XML Parser This package provides a simple parser which reads a XML document and output a tree structure, which does not need a pre-de

null 8 Jul 1, 2022
A simple json parser built using golang

jsonparser A simple json parser built using golang Installation: go get -u githu

Krisna Pranav 1 Dec 29, 2021
A NMEA parser library in pure Go

go-nmea This is a NMEA library for the Go programming language (Golang). Features Parse individual NMEA 0183 sentences Support for sentences with NMEA

Adrián Moreno 180 Jul 9, 2022
A shell parser, formatter, and interpreter with bash support; includes shfmt

sh A shell parser, formatter, and interpreter. Supports POSIX Shell, Bash, and mksh. Requires Go 1.14 or later. Quick start To parse shell scripts, in

Daniel Martí 5k Aug 7, 2022
A simple CSS parser and inliner in Go

douceur A simple CSS parser and inliner in Golang. Parser is vaguely inspired by CSS Syntax Module Level 3 and corresponding JS parser. Inliner only p

Aymerick 219 Jul 15, 2022
Simple HCL (HashiCorp Configuration Language) parser for your vars.

HCL to Markdown About To write a good documentation for terraform module, quite often we just need to print all our input variables as a fancy table.

Dmytro Shamenko 15 Dec 14, 2021
A markdown parser written in Go. Easy to extend, standard(CommonMark) compliant, well structured.

goldmark A Markdown parser written in Go. Easy to extend, standards-compliant, well-structured. goldmark is compliant with CommonMark 0.29. Motivation

Yusuke Inuzuka 2.3k Jul 30, 2022
Unified diff parser and printer for Go

go-diff Diff parser and printer for Go. Installing go get -u github.com/sourcegraph/go-diff/diff Usage It doesn't actually compute a diff. It only rea

Sourcegraph 367 Aug 5, 2022
A PDF renderer for the goldmark markdown parser.

goldmark-pdf goldmark-pdf is a renderer for goldmark that allows rendering to PDF. Reference See https://pkg.go.dev/github.com/stephenafamo/goldmark-p

Stephen Afam-Osemene 86 Jul 6, 2022
Experimental parser Angular template

Experimental parser Angular template This repository only shows what a parser on the Go might look like Benchmark 100k line of template Parser ms @ang

Rustam 8 Dec 15, 2021
A dead simple parser package for Go

A dead simple parser package for Go V2 Introduction Tutorial Tag syntax Overview Grammar syntax Capturing Capturing boolean value Streaming Lexing Sta

Alec Thomas 2.5k Jul 31, 2022
An extension to the Goldmark Markdown Parser

Goldmark-Highlight An extension to the Goldmark Markdown Parser which adds parsing / rendering capabilities for rendering highlighted text. Highlighte

Kevin Zuern 1 May 25, 2022
A parser combinator library for Go.

Takenoco A parser combinator library for Go. Examples CSV parser Dust - toy scripting language Usage Define the parser: package csv import ( "err

shellyln 3 Jul 1, 2022
Quick and simple parser for PFSense XML configuration files, good for auditing firewall rules

pfcfg-parser version 0.0.1 : 13 January 2022 A quick and simple parser for PFSense XML configuration files to generate a plain text file of the main c

Rory Campbell-Lange 0 Jan 13, 2022
Interpreted Programming Language built in Go. Lexer, Parser, AST, VM.

Gago | Programming Language Built in Go if you are looking for the docs, go here Gago is a interpreted programming language. It is fully written in Go

Glaukio 4 May 6, 2022
[Crawler/Scraper for Golang]🕷A lightweight distributed friendly Golang crawler framework.一个轻量的分布式友好的 Golang 爬虫框架。

Goribot 一个分布式友好的轻量的 Golang 爬虫框架。 完整文档 | Document !! Warning !! Goribot 已经被迁移到 Gospider|github.com/zhshch2002/gospider。修复了一些调度问题并分离了网络请求部分到另一个仓库。此仓库会继续

null 208 Jul 4, 2022
golang 在线预览word,excel,pdf,MarkDown(Online Preview Word,Excel,PPT,PDF,Image by Golang)

Go View File 在线体验地址 http://39.97.98.75:8082/view/upload (不会经常更新,保留最基本的预览功能。服务器配置较低,如果出现链接超时请等待几秒刷新重试,或者换Chrome) 目前已经完成 docker部署 (不用为运行环境烦恼) Wor

CZC 64 Jul 26, 2022