-
Notifications
You must be signed in to change notification settings - Fork 8.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[FAB-14941] move util.Flatten to localconfig
The orderer main uses the function to enumerate the current configuration. Change-Id: I8e4363dfd7ac53c356af271b7448915b5c77a230 Signed-off-by: Matthew Sykes <sykesmat@us.ibm.com>
- Loading branch information
Showing
5 changed files
with
126 additions
and
105 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/* | ||
Copyright IBM Corp. All Rights Reserved. | ||
SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package localconfig | ||
|
||
import ( | ||
"fmt" | ||
"reflect" | ||
) | ||
|
||
// Flatten performs a depth-first serialization of a struct to a slice of | ||
// strings. Each string will be formatted at 'path.to.leaf = value'. | ||
func Flatten(i interface{}) []string { | ||
var res []string | ||
flatten("", &res, reflect.ValueOf(i)) | ||
return res | ||
} | ||
|
||
// 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(k string, m *[]string, v reflect.Value) { | ||
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)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* | ||
Copyright IBM Corp. All Rights Reserved. | ||
SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package localconfig | ||
|
||
import ( | ||
"fmt" | ||
"reflect" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
type A struct { | ||
s string | ||
} | ||
|
||
type B struct { | ||
A A | ||
i int | ||
X string | ||
} | ||
|
||
type C struct{} | ||
|
||
type D struct { | ||
B B | ||
c *C | ||
} | ||
|
||
func (a A) String() string { | ||
return fmt.Sprintf("I'm '%s'", a.s) | ||
} | ||
|
||
func TestFlattenStruct(t *testing.T) { | ||
d := &D{ | ||
B: B{ | ||
A: A{ | ||
s: "foo", | ||
}, | ||
i: 42, | ||
X: "bar ", | ||
}, | ||
c: nil, | ||
} | ||
|
||
var x []string | ||
flatten("", &x, reflect.ValueOf(d)) | ||
assert.Equal(t, 4, len(x), "expect 3 items") | ||
assert.Equal(t, x[0], "B.A = I'm 'foo'") | ||
assert.Equal(t, x[1], "B.i = 42") | ||
assert.Equal(t, x[2], "B.X = \"bar \"") | ||
assert.Equal(t, x[3], "c =") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters