Remove unused code.
I was looking for an example of reflect and noticed that this code was unused.pull/7338/head
parent
77ec80f966
commit
d8db21478c
|
@ -1,189 +0,0 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
utilnet "k8s.io/apimachinery/pkg/util/net"
|
||||
)
|
||||
|
||||
// findNestedElement uses reflection to find the element corresponding to the dot-separated string parameter.
|
||||
func findNestedElement(s string, c interface{}) (reflect.Value, error) {
|
||||
fields := strings.Split(s, ".")
|
||||
|
||||
// Take the ValueOf to get a pointer, so we can actually mutate the element.
|
||||
e := reflect.Indirect(reflect.ValueOf(c).Elem())
|
||||
|
||||
for _, field := range fields {
|
||||
e = reflect.Indirect(e.FieldByName(field))
|
||||
|
||||
// FieldByName returns the zero value if the field does not exist.
|
||||
if e == (reflect.Value{}) {
|
||||
return e, fmt.Errorf("unable to find field by name: %s", field)
|
||||
}
|
||||
// Start the loop again, on the next level.
|
||||
}
|
||||
return e, nil
|
||||
}
|
||||
|
||||
// setElement sets the supplied element to the value in the supplied string. The string will be coerced to the correct type.
|
||||
func setElement(e reflect.Value, v string) error {
|
||||
switch e.Interface().(type) {
|
||||
case int, int32, int64:
|
||||
return convertInt(e, v)
|
||||
case string:
|
||||
return convertString(e, v)
|
||||
case float32, float64:
|
||||
return convertFloat(e, v)
|
||||
case bool:
|
||||
return convertBool(e, v)
|
||||
case net.IP:
|
||||
return convertIP(e, v)
|
||||
case net.IPNet:
|
||||
return convertCIDR(e, v)
|
||||
case utilnet.PortRange:
|
||||
return convertPortRange(e, v)
|
||||
case time.Duration:
|
||||
return convertDuration(e, v)
|
||||
case []string:
|
||||
vals := strings.Split(v, ",")
|
||||
e.Set(reflect.ValueOf(vals))
|
||||
case map[string]string:
|
||||
return convertMap(e, v)
|
||||
default:
|
||||
// Last ditch attempt to convert anything based on its underlying kind.
|
||||
// This covers any types that are aliased to a native type
|
||||
return convertKind(e, v)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func convertMap(e reflect.Value, v string) error {
|
||||
if e.IsNil() {
|
||||
e.Set(reflect.MakeMap(e.Type()))
|
||||
}
|
||||
vals := strings.Split(v, ",")
|
||||
for _, subitem := range vals {
|
||||
subvals := strings.FieldsFunc(subitem, func(c rune) bool {
|
||||
return c == '<' || c == '=' || c == '>'
|
||||
})
|
||||
if len(subvals) != 2 {
|
||||
return fmt.Errorf("unparsable %s", v)
|
||||
}
|
||||
e.SetMapIndex(reflect.ValueOf(subvals[0]), reflect.ValueOf(subvals[1]))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func convertKind(e reflect.Value, v string) error {
|
||||
switch e.Kind() {
|
||||
case reflect.Int, reflect.Int32, reflect.Int64:
|
||||
return convertInt(e, v)
|
||||
case reflect.String:
|
||||
return convertString(e, v)
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return convertFloat(e, v)
|
||||
case reflect.Bool:
|
||||
return convertBool(e, v)
|
||||
default:
|
||||
return fmt.Errorf("unable to set type %T", e.Kind())
|
||||
}
|
||||
}
|
||||
|
||||
func convertInt(e reflect.Value, v string) error {
|
||||
i, err := strconv.Atoi(v)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error converting input %s to an integer: %v", v, err)
|
||||
}
|
||||
e.SetInt(int64(i))
|
||||
return nil
|
||||
}
|
||||
|
||||
func convertString(e reflect.Value, v string) error {
|
||||
e.SetString(v)
|
||||
return nil
|
||||
}
|
||||
|
||||
func convertFloat(e reflect.Value, v string) error {
|
||||
f, err := strconv.ParseFloat(v, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error converting input %s to a float: %v", v, err)
|
||||
}
|
||||
e.SetFloat(f)
|
||||
return nil
|
||||
}
|
||||
|
||||
func convertBool(e reflect.Value, v string) error {
|
||||
b, err := strconv.ParseBool(v)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error converting input %s to a bool: %v", v, err)
|
||||
}
|
||||
e.SetBool(b)
|
||||
return nil
|
||||
}
|
||||
|
||||
func convertIP(e reflect.Value, v string) error {
|
||||
ip := net.ParseIP(v)
|
||||
if ip == nil {
|
||||
return fmt.Errorf("error converting input %s to an IP", v)
|
||||
}
|
||||
e.Set(reflect.ValueOf(ip))
|
||||
return nil
|
||||
}
|
||||
|
||||
func convertCIDR(e reflect.Value, v string) error {
|
||||
_, cidr, err := net.ParseCIDR(v)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error converting input %s to a CIDR: %v", v, err)
|
||||
}
|
||||
e.Set(reflect.ValueOf(*cidr))
|
||||
return nil
|
||||
}
|
||||
|
||||
func convertPortRange(e reflect.Value, v string) error {
|
||||
pr, err := utilnet.ParsePortRange(v)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error converting input %s to PortRange: %v", v, err)
|
||||
}
|
||||
e.Set(reflect.ValueOf(*pr))
|
||||
return nil
|
||||
}
|
||||
|
||||
func convertDuration(e reflect.Value, v string) error {
|
||||
dur, err := time.ParseDuration(v)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error converting input %s to Duration: %v", v, err)
|
||||
}
|
||||
e.Set(reflect.ValueOf(dur))
|
||||
return nil
|
||||
}
|
||||
|
||||
// FindAndSet sets the nested value.
|
||||
func FindAndSet(path string, c interface{}, value string) error {
|
||||
elem, err := findNestedElement(path, c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return setElement(elem, value)
|
||||
}
|
|
@ -1,197 +0,0 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
"math"
|
||||
"net"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
utilnet "k8s.io/apimachinery/pkg/util/net"
|
||||
)
|
||||
|
||||
type aliasedString string
|
||||
|
||||
type testConfig struct {
|
||||
A string
|
||||
B int
|
||||
C float32
|
||||
D subConfig1
|
||||
E *subConfig2
|
||||
}
|
||||
|
||||
type subConfig1 struct {
|
||||
F string
|
||||
G int
|
||||
H float32
|
||||
I subConfig3
|
||||
}
|
||||
|
||||
type subConfig2 struct {
|
||||
J string
|
||||
K int
|
||||
L float32
|
||||
}
|
||||
|
||||
type subConfig3 struct {
|
||||
M string
|
||||
N int
|
||||
O float32
|
||||
P bool
|
||||
Q net.IP
|
||||
R utilnet.PortRange
|
||||
S []string
|
||||
T aliasedString
|
||||
U net.IPNet
|
||||
V time.Duration
|
||||
}
|
||||
|
||||
func buildConfig() testConfig {
|
||||
_, cidr, _ := net.ParseCIDR("12.34.56.78/16")
|
||||
return testConfig{
|
||||
A: "foo",
|
||||
B: 1,
|
||||
C: 1.1,
|
||||
D: subConfig1{
|
||||
F: "bar",
|
||||
G: 2,
|
||||
H: 2.2,
|
||||
I: subConfig3{
|
||||
M: "baz",
|
||||
N: 3,
|
||||
O: 3.3,
|
||||
P: false,
|
||||
Q: net.ParseIP("12.34.56.78"),
|
||||
R: utilnet.PortRange{Base: 2, Size: 4},
|
||||
U: *cidr,
|
||||
V: 5 * time.Second,
|
||||
},
|
||||
},
|
||||
E: &subConfig2{
|
||||
J: "bat",
|
||||
K: 4,
|
||||
L: 4.4,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindNestedStrings(t *testing.T) {
|
||||
a := buildConfig()
|
||||
for _, tc := range []struct {
|
||||
input string
|
||||
output string
|
||||
}{
|
||||
{"A", "foo"},
|
||||
{"D.F", "bar"},
|
||||
{"D.I.M", "baz"},
|
||||
{"E.J", "bat"},
|
||||
} {
|
||||
v, err := findNestedElement(tc.input, &a)
|
||||
if err != nil {
|
||||
t.Fatalf("Did not expect error. Got: %v", err)
|
||||
}
|
||||
if v.String() != tc.output {
|
||||
t.Fatalf("Expected: %s, got %s", tc.output, v.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindNestedInts(t *testing.T) {
|
||||
a := buildConfig()
|
||||
|
||||
for _, tc := range []struct {
|
||||
input string
|
||||
output int64
|
||||
}{
|
||||
{"B", 1},
|
||||
{"D.G", 2},
|
||||
{"D.I.N", 3},
|
||||
{"E.K", 4},
|
||||
} {
|
||||
v, err := findNestedElement(tc.input, &a)
|
||||
if err != nil {
|
||||
t.Fatalf("Did not expect error. Got: %v", err)
|
||||
}
|
||||
if v.Int() != tc.output {
|
||||
t.Fatalf("Expected: %d, got %d", tc.output, v.Int())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func checkFloats(f1, f2 float64) bool {
|
||||
return math.Abs(f1-f2) < .00001
|
||||
}
|
||||
|
||||
func TestFindNestedFloats(t *testing.T) {
|
||||
a := buildConfig()
|
||||
for _, tc := range []struct {
|
||||
input string
|
||||
output float64
|
||||
}{
|
||||
{"C", 1.1},
|
||||
{"D.H", 2.2},
|
||||
{"D.I.O", 3.3},
|
||||
{"E.L", 4.4},
|
||||
} {
|
||||
v, err := findNestedElement(tc.input, &a)
|
||||
if err != nil {
|
||||
t.Fatalf("Did not expect error. Got: %v", err)
|
||||
}
|
||||
|
||||
// Floating point comparison is tricky.
|
||||
if !checkFloats(tc.output, v.Float()) {
|
||||
t.Fatalf("Expected: %v, got %v", tc.output, v.Float())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetElement(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
path string
|
||||
newval string
|
||||
checker func(testConfig) bool
|
||||
}{
|
||||
{"A", "newstring", func(t testConfig) bool { return t.A == "newstring" }},
|
||||
{"B", "13", func(t testConfig) bool { return t.B == 13 }},
|
||||
{"C", "3.14", func(t testConfig) bool { return checkFloats(float64(t.C), 3.14) }},
|
||||
{"D.F", "fizzbuzz", func(t testConfig) bool { return t.D.F == "fizzbuzz" }},
|
||||
{"D.G", "4", func(t testConfig) bool { return t.D.G == 4 }},
|
||||
{"D.H", "7.3", func(t testConfig) bool { return checkFloats(float64(t.D.H), 7.3) }},
|
||||
{"E.J", "otherstring", func(t testConfig) bool { return t.E.J == "otherstring" }},
|
||||
{"E.K", "17", func(t testConfig) bool { return t.E.K == 17 }},
|
||||
{"E.L", "1.234", func(t testConfig) bool { return checkFloats(float64(t.E.L), 1.234) }},
|
||||
{"D.I.P", "true", func(t testConfig) bool { return t.D.I.P == true }},
|
||||
{"D.I.P", "false", func(t testConfig) bool { return t.D.I.P == false }},
|
||||
{"D.I.Q", "11.22.33.44", func(t testConfig) bool { return t.D.I.Q.Equal(net.ParseIP("11.22.33.44")) }},
|
||||
{"D.I.R", "7-11", func(t testConfig) bool { return t.D.I.R.Base == 7 && t.D.I.R.Size == 5 }},
|
||||
{"D.I.S", "a,b", func(t testConfig) bool { return reflect.DeepEqual(t.D.I.S, []string{"a", "b"}) }},
|
||||
{"D.I.T", "foo", func(t testConfig) bool { return t.D.I.T == "foo" }},
|
||||
{"D.I.U", "11.22.0.0/16", func(t testConfig) bool { return t.D.I.U.String() == "11.22.0.0/16" }},
|
||||
{"D.I.V", "5s", func(t testConfig) bool { return t.D.I.V == 5*time.Second }},
|
||||
} {
|
||||
a := buildConfig()
|
||||
if err := FindAndSet(tc.path, &a, tc.newval); err != nil {
|
||||
t.Fatalf("Error setting value: %v", err)
|
||||
}
|
||||
if !tc.checker(a) {
|
||||
t.Fatalf("Error, values not correct: %v, %s, %s", a, tc.newval, tc.path)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue