github.com/anjalikarhana/fabric@v2.1.1+incompatible/orderer/common/localconfig/flatten.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package localconfig
     8  
     9  import (
    10  	"fmt"
    11  	"reflect"
    12  )
    13  
    14  // Flatten performs a depth-first serialization of a struct to a slice of
    15  // strings. Each string will be formatted at 'path.to.leaf = value'.
    16  func Flatten(i interface{}) []string {
    17  	var res []string
    18  	flatten("", &res, reflect.ValueOf(i))
    19  	return res
    20  }
    21  
    22  // flatten recursively retrieves every leaf node in a struct in depth-first fashion
    23  // and aggregate the results into given string slice with format: "path.to.leaf = value"
    24  // in the order of definition. Root name is ignored in the path. This helper function is
    25  // useful to pretty-print a struct, such as configs.
    26  // for example, given data structure:
    27  // A{
    28  //   B{
    29  //     C: "foo",
    30  //     D: 42,
    31  //   },
    32  //   E: nil,
    33  // }
    34  // it should yield a slice of string containing following items:
    35  // [
    36  //   "B.C = \"foo\"",
    37  //   "B.D = 42",
    38  //   "E =",
    39  // ]
    40  func flatten(k string, m *[]string, v reflect.Value) {
    41  	delimiter := "."
    42  	if k == "" {
    43  		delimiter = ""
    44  	}
    45  
    46  	switch v.Kind() {
    47  	case reflect.Ptr:
    48  		if v.IsNil() {
    49  			*m = append(*m, fmt.Sprintf("%s =", k))
    50  			return
    51  		}
    52  		flatten(k, m, v.Elem())
    53  	case reflect.Struct:
    54  		if x, ok := v.Interface().(fmt.Stringer); ok {
    55  			*m = append(*m, fmt.Sprintf("%s = %v", k, x))
    56  			return
    57  		}
    58  
    59  		for i := 0; i < v.NumField(); i++ {
    60  			flatten(k+delimiter+v.Type().Field(i).Name, m, v.Field(i))
    61  		}
    62  	case reflect.String:
    63  		// It is useful to quote string values
    64  		*m = append(*m, fmt.Sprintf("%s = \"%s\"", k, v))
    65  	default:
    66  		*m = append(*m, fmt.Sprintf("%s = %v", k, v))
    67  	}
    68  }