Home > Blockchain >  Go unmarshalling a toml which contains a hash table name
Go unmarshalling a toml which contains a hash table name

Time:10-20

With a toml parser for go (https://github.com/BurntSushi/toml)

I am trying to unmarshall the following toml file:

            type (
                fruitSpecs struct {
                    Id     int      `toml:"id"`
                    Name   string   `toml:"name"`
                }
            )
            blob := `
            [kiwi]
                id = 1234581941
                name = "kiwi"
            `
            o := &fruitSpecs{}
            err := toml.Unmarshal([]byte(blob), o)
            fmt.Println(o.Id)

It seems like when I use a table [kiwi] It does not seem like I can unmarshall it correctly.

If I remove the table name, I can succesfully grab the Id field.

I am missing some encapsulation when trying to successfully build the whole struct that will hold the data?

I have tried the following to add the table name, but without any positive outcome:

            type (
                fruitSpecs struct {
                    Id     int      `toml:"id"`
                    Name   string   `toml:"name"`
                }
                fruits struct {
                    fruit fruitSpecs
                }
            )
            blob := `
            [kiwi]
                id = 1234581941
                name = "kiwi"
            `
            o := &fruitSpecs{}
            err := toml.Unmarshal([]byte(blob), o)
            fmt.Println(o.Id)

But it errors with: o.Id undefined (type *fruitSpecs has no field or method Id)

CodePudding user response:

UPDATE 1: I've managed to decode it with a hash table name. See the following example for more details:

            type (
                fruitSpecs struct {
                    Id     int      `toml:"id"`
                    Name   string   `toml:"name"`
                }
                fruits struct {
                    fruit fruitSpecs `toml:"kiwi"`
                }
            )
            blob := `
            [kiwi]
                id = 1234581941
                name = "kiwi"
            `
            o := &fruits{}
            err := toml.Unmarshal([]byte(blob), o)
            fmt.Println(o.fruit.Id)

// CLI Output:
// 1234581941

Please note the three changes, adding the tag into the struct, o variable pointing to the general struct, and printing the id with the correct path (o.fruit.Id)

The problem here is that I need to parse more than one table, and specifying the table name in the tag is not viable.

Is there any way of telling burntsushi toml parse to ignore the table name and accept everything from it? Something like:

            type (
                fruitSpecs struct {
                    Id     int      `toml:"id"`
                    Name   string   `toml:"name"`
                }
                fruits struct {
                    fruit fruitSpecs `toml:"*"` // Do not filter by name, accept every table name entry
                }
            )
            blob := `
            [kiwi]
                id = 1234581941
                name = "kiwi"
            [banana]
                id = 9876544312
                name = "banana"
            `
            o := &fruits{}
            err := toml.Unmarshal([]byte(blob), o)
            fmt.Println(o.fruit.Id)
// Desired output:
// 1234581941
// 9876544312

UPDATE 2: Finally I managed to get all the fields containing Id with the following code:

            type (
                fruitSpecs struct {
                    Id     int      `toml:"id"`
                    Name   string   `toml:"name"`
                }
                fruit map[inteface{}]fruitSpecs
            )
            blob := `
            [kiwi]
                id = 1234581941
                name = "kiwi"
            [banana]
                id = 9876544312
                name = "banana"
            `
            var o fruit
            err := toml.Decode(blob, &fruit)
            for _, item := range o {
                fmt.Println(item.Id)
            }
// CLI Output:
// 1234581941
// 9876544312

Note the changes of using toml.Unmarshall to toml.Decode, generating into a map the struct of fruitSpecs and interating over the mapped struct.

This is how I resolved this issue.

Free software.

  •  Tags:  
  • go
  • Related