-
Notifications
You must be signed in to change notification settings - Fork 211
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unable to Unmarshal into *toml.Tree #333
Comments
Hi! Sorry it took a bit to get back to you. Unfortunately, go-toml is not great at unmarshaling unknown objects (main issue to track this is #337). If you are fine with parsing the file twice, you can unmarshal the outer struct, then replace its Hope that helps! package main
import (
"github.com/davecgh/go-spew/spew"
"github.com/pelletier/go-toml"
)
type outer struct {
Thing string
Other *toml.Tree // will not be filled with unmarshal
Asd struct {
X string
}
}
func main() {
const test = `
thing = "stuff"
[other]
stuff = "more stuff"
otherStuff = 1337
[asd]
x = "v"
`
tree, err := toml.Load(test)
if err != nil {
panic(err)
}
x := outer{}
err = toml.Unmarshal([]byte(test), &x)
if err != nil {
panic(err)
}
x.Other = tree.Get("other").(*toml.Tree)
spew.Dump(x)
/*
(main.outer) {
Thing: (string) (len=5) "stuff",
Other: (*toml.Tree)(0xc42008a660)(otherStuff = 1337
stuff = "more stuff"
),
Asd: (struct { X string }) {
X: (string) (len=1) "v"
}
}
*/
} |
Yeah thats about what I came to as a solution for a workaround, unfortunate that it doesnt work OOTB but its Im quite sure not a simple process to get that right. I may take a crack at it at some point if doing it the other way annoys me too much. Pretty much my only deviation from what you suggested is that I abuse a Tree from Load, rather than parsing twice: func makeConfig(tree *toml.Tree) (*Config, error) {
out := new(Config)
if err := tree.Unmarshal(out); err != nil {
return nil, err
}
if res, ok := tree.Get("connection.server").(*toml.Tree); ok {
out.Connection.RealConf = res
}
for name, game := range out.Games {
data := tree.GetPath([]string{"games", name, "transport"})
if res, ok := data.(*toml.Tree); ok {
game.Transport.RealConf = res
}
}
return out, nil
} |
Ha right, good call on unmarshaling the tree after parsed. This is definitely and highly requested issue that I haven’t had time to fix. |
Does #341 satisfy this requirement? |
I may be able to use it to reduce some boilerplate code in my unmarshal, but it becomes more boilerplate elsewhere where I'd need to convert from a The reason I need/want to go about this like this is that my main config package has no idea what some parts of its config represent, as they're based on other parts. e.g. the |
Describe the bug
I want to unmarshal parts of a TOML file into an
*toml.Tree
for later inspection and unmarshaling (in this case the type is not known to the main unmarshal code in my config code)To Reproduce
I tested this using a quick test file in my larger project while working out how to go about a few things. You can extract the toml data directly from here
Expected behavior
I expected
x.Other
to be filled with the same tree thatres.Get
returns, however what I got was an empty toml.Tree (it was not nil--but it was the zero value):entire object:
closer look at
x.Other
:type and content (via stringer) of return from res.Get:
Versions
github.com/pelletier/go-toml v1.6.0
Additional context
I'm not entirely familiar with how go-toml works as this is my first use of it, but as I understand your docs this should work?
The text was updated successfully, but these errors were encountered: