go-yaml / yaml

YAML support for the Go language.
Other
6.85k stars 1.05k forks source link

How to handle missing fields? I don't want them to be populated with default values. #505

Open omefire opened 5 years ago

omefire commented 5 years ago

I have a set of yaml files I'm dealing with that follow a particular schema. However, sometimes, the fields are not present in the yaml file. But they do get populated with default values when unmarshalled. i.e: an int field gets populated with value 0.

Is there a way to deal with that? I want to be able to know whether a field was found or not in the yaml file.

invidian commented 5 years ago

@omefire for that, you should make your fields a pointers, so string becomes *string. This way you can do foo == nil instead of foo == "" (Golang zero value for string type). This is the Go way of marking struct fields as optional.

When you want to achieve the same when marshalling, use optional keyword.

gurza commented 3 years ago

@omefire try to use UnmarshalStrict() instead of Unmarshal(). This method is implemented in v2 https://pkg.go.dev/gopkg.in/yaml.v2#UnmarshalStrict. And add omitempty tag for optional fields.

For example

type Config struct {
    Port        int    `yaml:"port"`
    EmailSender string `yaml:"email_sender"`

    // AWS configuration
    AWS struct {
        Region          string  `yaml:"region"`
        AccessKeyID     *string `yaml:"access_key_id,omitempty"`
        SecretAccessKey *string `yaml:"secret_access_key,omitempty"`
    } `yaml:"aws"`
}

EDITED

Sorry, it will not work for you. UnmarshalStrict() check fields of config file, not fields of structure.

AlexanderMakarov commented 4 months ago
    cfg := &Config{}
    decoder := yaml.NewDecoder(strings.NewReader(string(buf)))
    decoder.KnownFields(true) // Disallow unknown fields
    if err = decoder.Decode(cfg); err != nil {
        if err.Error() == "EOF" {
            return nil, fmt.Errorf("can't decode YAML from configuration file '%s': %v", filename, err)
        }
        return nil, err
    }

Works for me in 2024/Go 1.22.2.