Skip to content

Instantly share code, notes, and snippets.

@velp
Last active April 20, 2020 12:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save velp/85a0a26fc20b90a07bae75954f50ddc3 to your computer and use it in GitHub Desktop.
Save velp/85a0a26fc20b90a07bae75954f50ddc3 to your computer and use it in GitHub Desktop.
Goalng code snippets

YAML parse string/array in one field and parse string/map in one field

import (
    "fmt"
    "strconv"
    "strings"
    "gopkg.in/yaml.v2"
)

/* StringMap represents special type to parse array of string and map of string
declaration in one field.
For example this type can parse:
    labels:
      com.example.description: "Accounting webapp"
      com.example.department: "Finance"
      com.example.label-with-empty-value: ""

and:
    labels:
    - "com.example.description=Accounting webapp"
    - "com.example.department=Finance"
    - "com.example.label-with-empty-value"

as the same time.
*/
type StringMap map[string]string

func (m *StringMap) UnmarshalYAML(unmarshal func(interface{}) error) error {
    var mapValues map[string]string
    if err := unmarshal(&mapValues); err != nil {
        var arrayValues []string
        if err := unmarshal(&arrayValues); err != nil {
            return fmt.Errorf("incorrect value: %s, should be array or map", err)
        }
        mapValues = make(map[string]string, len(arrayValues))
        for _, val := range arrayValues {
            parsed := strings.Split(val, "=")
            if len(parsed) < 2 {
                return fmt.Errorf("incorrect value for array element %s, should be in format KEY=VALUE", val)
            }
            mapValues[parsed[0]] = strings.Join(parsed[1:], "")
        }
    }
    *m = mapValues
    return nil
}

/* StringArray represents special type for docker compose fields
this type will parse:
    command: >
      bash -c
        "echo test"
or:
    command: ["bash", "-c", "echo test"]
or:
    command: "bash -c echo test"
*/
type StringArray []string

func (s *StringArray) UnmarshalYAML(unmarshal func(interface{}) error) error {
    var values []string
    if err := unmarshal(&values); err != nil {
        var value string
        if err := unmarshal(&value); err != nil {
            return fmt.Errorf("incorrect value, should be array or string")
        }
        values = make([]string, 1)
        values[0] = value
    }
    *s = values
    return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment