Skip to content

Commit 93be898

Browse files
committed
chore: remove mitchellh/copystructure dependency
1 parent 989da45 commit 93be898

File tree

5 files changed

+462
-22
lines changed

5 files changed

+462
-22
lines changed

copystructure.go

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package sprig
2+
3+
import (
4+
"fmt"
5+
"reflect"
6+
)
7+
8+
// deepcopy performs a deep copy of the given interface{}.
9+
func deepcopy(src interface{}) (interface{}, error) {
10+
if src == nil {
11+
return make(map[string]interface{}), nil
12+
}
13+
return copyValue(reflect.ValueOf(src))
14+
}
15+
16+
// copyValue handles copying using reflection for non-map types
17+
func copyValue(original reflect.Value) (interface{}, error) {
18+
switch original.Kind() {
19+
case reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32,
20+
reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32,
21+
reflect.Uint64, reflect.Uintptr, reflect.Float32, reflect.Float64,
22+
reflect.Complex64, reflect.Complex128, reflect.String, reflect.Array:
23+
return original.Interface(), nil
24+
25+
case reflect.Interface:
26+
if original.IsNil() {
27+
return original.Interface(), nil
28+
}
29+
return copyValue(original.Elem())
30+
31+
case reflect.Map:
32+
if original.IsNil() {
33+
return original.Interface(), nil
34+
}
35+
copied := reflect.MakeMap(original.Type())
36+
37+
var err error
38+
var child interface{}
39+
iter := original.MapRange()
40+
for iter.Next() {
41+
key := iter.Key()
42+
value := iter.Value()
43+
44+
if value.Kind() == reflect.Interface && value.IsNil() {
45+
copied.SetMapIndex(key, value)
46+
continue
47+
}
48+
49+
child, err = copyValue(value)
50+
if err != nil {
51+
return nil, err
52+
}
53+
copied.SetMapIndex(key, reflect.ValueOf(child))
54+
}
55+
return copied.Interface(), nil
56+
57+
case reflect.Pointer:
58+
if original.IsNil() {
59+
return original.Interface(), nil
60+
}
61+
copied, err := copyValue(original.Elem())
62+
if err != nil {
63+
return nil, err
64+
}
65+
ptr := reflect.New(original.Type().Elem())
66+
ptr.Elem().Set(reflect.ValueOf(copied))
67+
return ptr.Interface(), nil
68+
69+
case reflect.Slice:
70+
if original.IsNil() {
71+
return original.Interface(), nil
72+
}
73+
copied := reflect.MakeSlice(original.Type(), original.Len(), original.Cap())
74+
for i := 0; i < original.Len(); i++ {
75+
val, err := copyValue(original.Index(i))
76+
if err != nil {
77+
return nil, err
78+
}
79+
copied.Index(i).Set(reflect.ValueOf(val))
80+
}
81+
return copied.Interface(), nil
82+
83+
case reflect.Struct:
84+
copied := reflect.New(original.Type()).Elem()
85+
for i := 0; i < original.NumField(); i++ {
86+
elem, err := copyValue(original.Field(i))
87+
if err != nil {
88+
return nil, err
89+
}
90+
copied.Field(i).Set(reflect.ValueOf(elem))
91+
}
92+
return copied.Interface(), nil
93+
94+
case reflect.Func, reflect.Chan, reflect.UnsafePointer:
95+
if original.IsNil() {
96+
return original.Interface(), nil
97+
}
98+
return original.Interface(), nil
99+
100+
default:
101+
return original.Interface(), fmt.Errorf("unsupported type %v", original)
102+
}
103+
}

0 commit comments

Comments
 (0)