BurntSushi / toml

TOML parser for Golang with reflection.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How to parse undecoded data?

Octogonapus opened this issue · comments

commented

I'm trying to parse Julia Manifest files, which look something like this:

[[Dates]]
deps = ["Printf"]
uuid = "ade2ca70-3891-5945-98fb-dc099432e06a"

[[JSON]]
deps = ["Dates", "Mmap", "Parsers", "Unicode"]
git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a"
uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
version = "0.21.4"

<more omitted>

I can't write a struct to help unmarshal this data because I don't know the values in the Manifest -- this code is generic against all Manifests. Can this library parse data of this format? I saw Metadata and Undecoded() in the docs, but I don't see a way to go from there to fully parsed data. My end goal is to parse this into a map[string][]Dep where the key is the table name (e.g. Dates) and Dep is:

type Dep struct {
	Deps        []string `toml:"deps"`
	GitTreeSHA1 string   `toml:"git-tree-sha1"`
	UUID        string   `toml:"uuid"`
	Version     string   `toml:"version"`
}

Is this possible? Any help is appreciated!

You can scan it to a map of slices:

package main

import (
	"fmt"

	"github.com/BurntSushi/toml"
)

func main() {
	t := `
[[Dates]]
deps = ["Printf"]
uuid = "ade2ca70-3891-5945-98fb-dc099432e06a"

[[JSON]]
deps = ["Dates", "Mmap", "Parsers", "Unicode"]
git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a"
uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
version = "0.21.4"
`

	var pkgs map[string][]struct {
		Deps        []string
		UUID        string
		GitTreeSHA1 string
		Version     string
	}
	_, err := toml.Decode(t, &pkgs)
	if err != nil {
		panic(err)
	}

	for name, pkg := range pkgs {
		fmt.Println(name)
		for i, p := range pkg {
			fmt.Println("  ", i, "=>", p.Deps)
		}
	}
}

Which outputs:

Dates
   0 => [Printf]
JSON
   0 => [Dates Mmap Parsers Unicode]

I don't know the full syntax of these files, but that works for your example anyway.

Usually the easiest way to see the structure is to scan it to map[string]any:

var pkgs map[string]any
_, err := toml.Decode(t, &pkgs)
if err != nil {
	panic(err)
}

for name, pkg := range pkgs {
	fmt.Println(name)
	fmt.Println("  ", pkg)
}

Which outputs:

Dates
    [map[deps:[Printf] uuid:ade2ca70-3891-5945-98fb-dc099432e06a]]
JSON
    [map[deps:[Dates Mmap Parsers Unicode] git-tree-sha1:31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a uuid:682c06a0-de6a-54ab-a142-c8b1cf79cde6 version:0.21.4]]

And should make the structure fairly clear (can also print as JSON).

commented

Great, thanks!