Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package common
- import (
- "fmt"
- "reflect"
- )
- // `flatten` recursively retrieves every leaf node in a struct in depth-first fashion
- // and aggregate the results into given string slice with format: "path.to.leaf = value"
- // in the order of definition. Root name is ignored in the path. This helper function is
- // useful to pretty-print a struct, such as configs.
- // for example, given data structure:
- // A{
- // B{
- // C: "foo",
- // D: 42,
- // },
- // E: nil,
- // }
- // it should yield a slice of string containing following items:
- // [
- // "B.C = \"foo\"",
- // "B.D = 42",
- // "E =",
- // ]
- func Flatten(i interface{}) []string {
- var res []string
- flatten("", &res, reflect.ValueOf(i))
- return res
- }
- const DELIMITER = "."
- func flatten(k string, m *[]string, v reflect.Value) {
- delimiter := DELIMITER
- if k == "" {
- delimiter = ""
- }
- switch v.Kind() {
- case reflect.Ptr:
- if v.IsNil() {
- *m = append(*m, fmt.Sprintf("%s =", k))
- return
- }
- flatten(k, m, v.Elem())
- case reflect.Struct:
- if x, ok := v.Interface().(fmt.Stringer); ok {
- *m = append(*m, fmt.Sprintf("%s = %v", k, x))
- return
- }
- for i := 0; i < v.NumField(); i++ {
- flatten(k+delimiter+v.Type().Field(i).Name, m, v.Field(i))
- }
- case reflect.String:
- // It is useful to quote string values
- *m = append(*m, fmt.Sprintf("%s = \"%s\"", k, v))
- default:
- *m = append(*m, fmt.Sprintf("%s = %v", k, v))
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement