mapstructure

repository·main·Indexed 27 days ago

https://github.com/mitchellh/mapstructure

A Go library for decoding generic map values into native Go structures and vice versa. It provides robust error handling, support for custom struct tags (such as squash and remain), and a flexible DecodeHook system for data transformation. The library includes specialized functions like WeakDecode for loose type conversion and DecodeMetadata for tracking used, unused, and unset keys during the decoding process.

Tokens
2.1K
Snippets
1
Records
22
Agent score
92%

What's inside mapstructure

  1. Decode generic maps into Go structures

    main
    Use mapstructure to decode values from a map[string]interface{} into a native Go structure. This is particularly useful when dealing with data streams (like JSON or Gob) where the final structure depends on values found within the data itself (e.g., a type field that determines which struct should be used).
  2. Use struct tags to control decoding behavior

    main

    You can use struct tags to customize how mapstructure maps input data to your Go structs. The library supports several special tag options:

    • squash: When applied to an anonymous (embedded) struct field, it flattens the fields of the embedded struct into the parent struct level. This is controlled by the Squash configuration setting.
    • remain: When applied to a field, any keys in the input map that do not match other fields in the struct will be decoded into this field. The remain field must be a map[interface{}]interface{} or similar map type.
    • [tagName]: The name of the tag used for mapping (e.g., mapstructure) is configurable via DecoderConfig.TagName.
  3. Use struct tags for field mapping

    main

    By default, mapstructure matches map keys to struct field names case-insensitively. You can customize this using the mapstructure tag.

    Renaming Fields Use the tag to map a specific key to a field:

    type User struct {
        Username string `mapstructure:"user"` // matches key "user"
    }

    Squashing Embedded Structs To treat an embedded struct as if its fields were part of the parent struct (instead of requiring a nested map), use the ,squash suffix:

    type Person struct {
        Name string
    }
    
    type Friend struct {
        Person `mapstructure:",squash"` // matches "name" directly in the input map
    }

    Collecting Remainder Values To capture all keys that were not mapped to a struct field, use the ,remain suffix on a map field:

    type Friend struct {
        Name  string                 `mapstructure:"name"` 
        Other map[string]interface{} `mapstructure:",remain"` // captures everything else
    }

    Omitting Empty Values When decoding from a struct to another type, use ,omitempty to skip fields that hold their type's zero value:

    type Source struct {
        Age int `mapstructure:",omitempty"` 
    }
  4. Configure name matching behavior

    main
    By default, mapstructure looks for exact matches between map keys and struct field names (or their tags). You can customize this behavior using the MatchName function in DecoderConfig. This allows for custom logic such as case-insensitive matching or handling different naming conventions (e.g., snake_case to PascalCase).
  5. Handle unused or unset fields via DecoderConfig

    main

    The DecoderConfig allows you to enforce strictness during the decoding process by enabling error reporting for missing or extra data:

    • ErrorUnused: If set to true, the decoder will return an error if the input map contains keys that do not match any fields in the target struct.
    • ErrorUnset: If set to true, the decoder will return an error if the target struct has fields that were not provided in the input map.
    • Metadata: If you provide a Metadata object in your configuration, the decoder will populate it with lists of Unused and Unset keys (using dot-notation for nested paths) instead of returning an error.
  6. Configure the decoder with DecoderConfig

    main

    For fine-grained control over the decoding process, create a Decoder using NewDecoder with a DecoderConfig struct.

    Key configuration options include:

    • DecodeHook: A callback for data transformations before decoding.
    • ErrorUnused: If true, returns an error if the input contains keys that don't match any struct fields.
    • ErrorUnset: If true, returns an error if struct fields are not populated by the input.
    • ZeroFields: If true, zeros out the destination fields before decoding (otherwise, it performs a merge).
    • WeaklyTypedInput: Enables loose type conversions (e.g., "1" to 1, true to 1).
    • Squash: Automatically squashes embedded structs.
    • TagName: The struct tag name to use (defaults to "mapstructure").
    • IgnoreUntaggedFields: If true, ignores struct fields that do not have an explicit tag.
  7. Compose multiple DecodeHookFuncs with ComposeDecodeHookFunc

    main
    Use ComposeDecodeHookFunc to create a single DecodeHookFunc that executes a sequence of hooks. The hooks are called in the order provided, and the output of one hook is passed as the input to the next. If any hook in the chain returns an error, the entire composed hook returns that error.