Skip to content

Commit b1e5a2a

Browse files
Merge pull request #238 from spf13/generic
Generic
2 parents 55a197b + fe0d3c4 commit b1e5a2a

File tree

1 file changed

+84
-154
lines changed

1 file changed

+84
-154
lines changed

caste.go

Lines changed: 84 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,36 +1000,57 @@ func ToStringE(i interface{}) (string, error) {
10001000
}
10011001
}
10021002

1003-
// ToStringMapStringE casts an interface to a map[string]string type.
1004-
func ToStringMapStringE(i interface{}) (map[string]string, error) {
1005-
m := map[string]string{}
1003+
func toMapE[K comparable, V any](i any, keyFn func(any) K, valFn func(any) V) (map[K]V, error) {
1004+
m := map[K]V{}
1005+
1006+
if i == nil {
1007+
return m, fmt.Errorf("unable to cast %#v of type %T to %T", i, i, m)
1008+
}
10061009

10071010
switch v := i.(type) {
1008-
case map[string]string:
1011+
case map[K]V:
10091012
return v, nil
1010-
case map[string]interface{}:
1013+
1014+
case map[K]any:
10111015
for k, val := range v {
1012-
m[ToString(k)] = ToString(val)
1016+
m[k] = valFn(val)
10131017
}
1018+
10141019
return m, nil
1015-
case map[interface{}]string:
1020+
1021+
case map[any]V:
10161022
for k, val := range v {
1017-
m[ToString(k)] = ToString(val)
1023+
m[keyFn(k)] = val
10181024
}
1025+
10191026
return m, nil
1020-
case map[interface{}]interface{}:
1027+
1028+
case map[any]any:
10211029
for k, val := range v {
1022-
m[ToString(k)] = ToString(val)
1030+
m[keyFn(k)] = valFn(val)
10231031
}
1032+
10241033
return m, nil
1034+
10251035
case string:
10261036
err := jsonStringToObject(v, &m)
1037+
10271038
return m, err
1039+
10281040
default:
1029-
return m, fmt.Errorf("unable to cast %#v of type %T to map[string]string", i, i)
1041+
return m, fmt.Errorf("unable to cast %#v of type %T to %T", i, i, m)
10301042
}
10311043
}
10321044

1045+
func toStringMapE[T any](i any, fn func(any) T) (map[string]T, error) {
1046+
return toMapE(i, ToString, fn)
1047+
}
1048+
1049+
// ToStringMapStringE casts an interface to a map[string]string type.
1050+
func ToStringMapStringE(i any) (map[string]string, error) {
1051+
return toStringMapE(i, ToString)
1052+
}
1053+
10331054
// ToStringMapStringSliceE casts an interface to a map[string][]string type.
10341055
func ToStringMapStringSliceE(i interface{}) (map[string][]string, error) {
10351056
m := map[string][]string{}
@@ -1096,130 +1117,83 @@ func ToStringMapStringSliceE(i interface{}) (map[string][]string, error) {
10961117

10971118
// ToStringMapBoolE casts an interface to a map[string]bool type.
10981119
func ToStringMapBoolE(i interface{}) (map[string]bool, error) {
1099-
m := map[string]bool{}
1100-
1101-
switch v := i.(type) {
1102-
case map[interface{}]interface{}:
1103-
for k, val := range v {
1104-
m[ToString(k)] = ToBool(val)
1105-
}
1106-
return m, nil
1107-
case map[string]interface{}:
1108-
for k, val := range v {
1109-
m[ToString(k)] = ToBool(val)
1110-
}
1111-
return m, nil
1112-
case map[string]bool:
1113-
return v, nil
1114-
case string:
1115-
err := jsonStringToObject(v, &m)
1116-
return m, err
1117-
default:
1118-
return m, fmt.Errorf("unable to cast %#v of type %T to map[string]bool", i, i)
1119-
}
1120+
return toStringMapE(i, ToBool)
11201121
}
11211122

11221123
// ToStringMapE casts an interface to a map[string]interface{} type.
11231124
func ToStringMapE(i interface{}) (map[string]interface{}, error) {
1124-
m := map[string]interface{}{}
1125+
fn := func(i any) any { return i }
11251126

1126-
switch v := i.(type) {
1127-
case map[interface{}]interface{}:
1128-
for k, val := range v {
1129-
m[ToString(k)] = val
1130-
}
1131-
return m, nil
1132-
case map[string]interface{}:
1133-
return v, nil
1134-
case string:
1135-
err := jsonStringToObject(v, &m)
1136-
return m, err
1137-
default:
1138-
return m, fmt.Errorf("unable to cast %#v of type %T to map[string]interface{}", i, i)
1139-
}
1127+
return toStringMapE(i, fn)
11401128
}
11411129

1142-
// ToStringMapIntE casts an interface to a map[string]int{} type.
1143-
func ToStringMapIntE(i interface{}) (map[string]int, error) {
1144-
m := map[string]int{}
1130+
func toStringMapIntE[T int | int64](i any, fn func(any) T, fnE func(any) (T, error)) (map[string]T, error) {
1131+
m := map[string]T{}
1132+
11451133
if i == nil {
1146-
return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int", i, i)
1134+
return m, fmt.Errorf("unable to cast %#v of type %T to %T", i, i, m)
11471135
}
11481136

11491137
switch v := i.(type) {
1150-
case map[interface{}]interface{}:
1151-
for k, val := range v {
1152-
m[ToString(k)] = ToInt(val)
1153-
}
1154-
return m, nil
1155-
case map[string]interface{}:
1156-
for k, val := range v {
1157-
m[k] = ToInt(val)
1158-
}
1159-
return m, nil
1160-
case map[string]int:
1138+
case map[string]T:
11611139
return v, nil
1162-
case string:
1163-
err := jsonStringToObject(v, &m)
1164-
return m, err
1165-
}
11661140

1167-
if reflect.TypeOf(i).Kind() != reflect.Map {
1168-
return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int", i, i)
1169-
}
1170-
1171-
mVal := reflect.ValueOf(m)
1172-
v := reflect.ValueOf(i)
1173-
for _, keyVal := range v.MapKeys() {
1174-
val, err := ToIntE(v.MapIndex(keyVal).Interface())
1175-
if err != nil {
1176-
return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int", i, i)
1141+
case map[string]any:
1142+
for k, val := range v {
1143+
m[k] = fn(val)
11771144
}
1178-
mVal.SetMapIndex(keyVal, reflect.ValueOf(val))
1179-
}
1180-
return m, nil
1181-
}
11821145

1183-
// ToStringMapInt64E casts an interface to a map[string]int64{} type.
1184-
func ToStringMapInt64E(i interface{}) (map[string]int64, error) {
1185-
m := map[string]int64{}
1186-
if i == nil {
1187-
return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int64", i, i)
1188-
}
1146+
return m, nil
11891147

1190-
switch v := i.(type) {
1191-
case map[interface{}]interface{}:
1148+
case map[any]T:
11921149
for k, val := range v {
1193-
m[ToString(k)] = ToInt64(val)
1150+
m[ToString(k)] = val
11941151
}
1152+
11951153
return m, nil
1196-
case map[string]interface{}:
1154+
1155+
case map[any]any:
11971156
for k, val := range v {
1198-
m[k] = ToInt64(val)
1157+
m[ToString(k)] = fn(val)
11991158
}
1159+
12001160
return m, nil
1201-
case map[string]int64:
1202-
return v, nil
1161+
12031162
case string:
12041163
err := jsonStringToObject(v, &m)
1164+
12051165
return m, err
12061166
}
12071167

12081168
if reflect.TypeOf(i).Kind() != reflect.Map {
1209-
return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int64", i, i)
1169+
return m, fmt.Errorf("unable to cast %#v of type %T to %T", i, i, m)
12101170
}
1171+
12111172
mVal := reflect.ValueOf(m)
12121173
v := reflect.ValueOf(i)
1174+
12131175
for _, keyVal := range v.MapKeys() {
1214-
val, err := ToInt64E(v.MapIndex(keyVal).Interface())
1176+
val, err := fnE(v.MapIndex(keyVal).Interface())
12151177
if err != nil {
1216-
return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int64", i, i)
1178+
return m, fmt.Errorf("unable to cast %#v of type %T to %T", i, i, m)
12171179
}
1180+
12181181
mVal.SetMapIndex(keyVal, reflect.ValueOf(val))
12191182
}
1183+
12201184
return m, nil
12211185
}
12221186

1187+
// ToStringMapIntE casts an interface to a map[string]int{} type.
1188+
func ToStringMapIntE(i any) (map[string]int, error) {
1189+
return toStringMapIntE(i, ToInt, ToIntE)
1190+
}
1191+
1192+
// ToStringMapInt64E casts an interface to a map[string]int64{} type.
1193+
func ToStringMapInt64E(i interface{}) (map[string]int64, error) {
1194+
return toStringMapIntE(i, ToInt64, ToInt64E)
1195+
}
1196+
12231197
// ToSliceE casts an interface to a []interface{} type.
12241198
func ToSliceE(i interface{}) ([]interface{}, error) {
12251199
var s []interface{}
@@ -1237,35 +1211,39 @@ func ToSliceE(i interface{}) ([]interface{}, error) {
12371211
}
12381212
}
12391213

1240-
// ToBoolSliceE casts an interface to a []bool type.
1241-
func ToBoolSliceE(i interface{}) ([]bool, error) {
1214+
func toSliceE[T any](i any, fn func(any) (T, error)) ([]T, error) {
12421215
if i == nil {
1243-
return []bool{}, fmt.Errorf("unable to cast %#v of type %T to []bool", i, i)
1216+
return []T{}, fmt.Errorf("unable to cast %#v of type %T to %T", i, i, []T{})
12441217
}
12451218

12461219
switch v := i.(type) {
1247-
case []bool:
1220+
case []T:
12481221
return v, nil
12491222
}
12501223

12511224
kind := reflect.TypeOf(i).Kind()
12521225
switch kind {
12531226
case reflect.Slice, reflect.Array:
12541227
s := reflect.ValueOf(i)
1255-
a := make([]bool, s.Len())
1228+
a := make([]T, s.Len())
12561229
for j := 0; j < s.Len(); j++ {
1257-
val, err := ToBoolE(s.Index(j).Interface())
1230+
val, err := fn(s.Index(j).Interface())
12581231
if err != nil {
1259-
return []bool{}, fmt.Errorf("unable to cast %#v of type %T to []bool", i, i)
1232+
return []T{}, fmt.Errorf("unable to cast %#v of type %T to %T", i, i, []T{})
12601233
}
12611234
a[j] = val
12621235
}
12631236
return a, nil
12641237
default:
1265-
return []bool{}, fmt.Errorf("unable to cast %#v of type %T to []bool", i, i)
1238+
return []T{}, fmt.Errorf("unable to cast %#v of type %T to %T", i, i, []T{})
12661239
}
12671240
}
12681241

1242+
// ToBoolSliceE casts an interface to a []bool type.
1243+
func ToBoolSliceE(i interface{}) ([]bool, error) {
1244+
return toSliceE(i, ToBoolE)
1245+
}
1246+
12691247
// ToStringSliceE casts an interface to a []string type.
12701248
func ToStringSliceE(i interface{}) ([]string, error) {
12711249
var a []string
@@ -1328,60 +1306,12 @@ func ToStringSliceE(i interface{}) ([]string, error) {
13281306

13291307
// ToIntSliceE casts an interface to a []int type.
13301308
func ToIntSliceE(i interface{}) ([]int, error) {
1331-
if i == nil {
1332-
return []int{}, fmt.Errorf("unable to cast %#v of type %T to []int", i, i)
1333-
}
1334-
1335-
switch v := i.(type) {
1336-
case []int:
1337-
return v, nil
1338-
}
1339-
1340-
kind := reflect.TypeOf(i).Kind()
1341-
switch kind {
1342-
case reflect.Slice, reflect.Array:
1343-
s := reflect.ValueOf(i)
1344-
a := make([]int, s.Len())
1345-
for j := 0; j < s.Len(); j++ {
1346-
val, err := ToIntE(s.Index(j).Interface())
1347-
if err != nil {
1348-
return []int{}, fmt.Errorf("unable to cast %#v of type %T to []int", i, i)
1349-
}
1350-
a[j] = val
1351-
}
1352-
return a, nil
1353-
default:
1354-
return []int{}, fmt.Errorf("unable to cast %#v of type %T to []int", i, i)
1355-
}
1309+
return toSliceE(i, ToIntE)
13561310
}
13571311

13581312
// ToDurationSliceE casts an interface to a []time.Duration type.
13591313
func ToDurationSliceE(i interface{}) ([]time.Duration, error) {
1360-
if i == nil {
1361-
return []time.Duration{}, fmt.Errorf("unable to cast %#v of type %T to []time.Duration", i, i)
1362-
}
1363-
1364-
switch v := i.(type) {
1365-
case []time.Duration:
1366-
return v, nil
1367-
}
1368-
1369-
kind := reflect.TypeOf(i).Kind()
1370-
switch kind {
1371-
case reflect.Slice, reflect.Array:
1372-
s := reflect.ValueOf(i)
1373-
a := make([]time.Duration, s.Len())
1374-
for j := 0; j < s.Len(); j++ {
1375-
val, err := ToDurationE(s.Index(j).Interface())
1376-
if err != nil {
1377-
return []time.Duration{}, fmt.Errorf("unable to cast %#v of type %T to []time.Duration", i, i)
1378-
}
1379-
a[j] = val
1380-
}
1381-
return a, nil
1382-
default:
1383-
return []time.Duration{}, fmt.Errorf("unable to cast %#v of type %T to []time.Duration", i, i)
1384-
}
1314+
return toSliceE(i, ToDurationE)
13851315
}
13861316

13871317
// StringToDate attempts to parse a string into a time.Time type using a

0 commit comments

Comments
 (0)