pelletier / go-toml

Go library for the TOML file format
https://github.com/pelletier/go-toml
Other
1.67k stars 208 forks source link

Keys are being deleted during Marshal() #932

Closed TLINDEN closed 4 months ago

TLINDEN commented 4 months ago

Describe the bug When marshalling a struct containing the key y, the key is omitted. And, when marshalling a struct with two keys YES and yes only one of them makes it to the output.

To Reproduce

    po := Punkt{4, 6, 8}
    fmt.Printf("Punkt: %#v\n", po)

    b, err := toml.Marshal(po)
    if err != nil {
        panic(err)
    }
    fmt.Printf("TOML:\n%s\n", string(b))

    type Punkt2 struct {
        y int
    }

        // try with y alone
    po2 := Punkt2{4}
    fmt.Printf("Punkt2: %#v\n", po2)

    b, err = toml.Marshal(po2)
    if err != nil {
        panic(err)
    }
    fmt.Printf("TOML:\n%s\n", string(b))

Output:

Punkt: main.Punkt{y:4, YES:6, yes:8}
TOML:
YES = 6

Punkt2: main.Punkt2{y:4}
TOML:

Expected behavior According to the documentation:

When encoding structs, fields are encoded in order of definition, with their exact name.

I could not find any section where it describes this behavior.

Versions

Additional context I encountered a similar bug in gopkg.in/yaml.v3 and wanted to switch to TOML because of this just to discover a similar strange behavior.

moorereason commented 4 months ago

The same behavior occurs with package json (see https://play.golang.com/p/95ADPcmOZfl). The issue is that marshaling in Go only works with exported struct fields (that is, the first character must be an uppercase letter), so you need to use struct field tags to tell the package that the encoded field name is different from the exact struct field name. A JSON example: https://play.golang.com/p/cKikjpPuu2x

TLINDEN commented 4 months ago

Hi,

thanks a lot! I seem to forget this upper case character thing regularly :)