7// FillNil returns a modified value with nil maps/slices replaced with empty
9func FillNil(rv reflect.Value) (nv reflect.Value, changed bool) {
12 for i := 0; i < rv.NumField(); i++ {
13 if !rv.Type().Field(i).IsExported() {
17 nvv, ch := FillNil(vv)
18 if ch && !rv.CanSet() {
19 // Make struct settable.
20 nrv := reflect.New(rv.Type()).Elem()
21 for j := 0; j < rv.NumField(); j++ {
22 nrv.Field(j).Set(rv.Field(j))
34 return reflect.MakeSlice(rv.Type(), 0, 0), true
37 for i := 0; i < n; i++ {
39 nrv, ch := FillNil(rve)
47 return reflect.MakeMap(rv.Type()), true
51 erv, ch := FillNil(i.Value())
54 rv.SetMapIndex(i.Key(), erv)
65// FillExample returns a modified value with nil/empty maps/slices/pointers values
66// replaced with non-empty versions, for more helpful examples of types. Useful for
67// documenting JSON representations of types.
68func FillExample(seen []reflect.Type, rv reflect.Value) reflect.Value {
70 seen = make([]reflect.Type, 100)
73 // Prevent recursive filling.
76 for i, t := range seen {
93 for i := 0; i < rv.NumField(); i++ {
94 if !rvt.Field(i).IsExported() {
98 vv.Set(FillExample(seen, vv))
101 ev := FillExample(seen, reflect.New(rvt.Elem()).Elem())
102 return reflect.Append(rv, ev)
104 vv := FillExample(seen, reflect.New(rvt.Elem()).Elem())
105 nv := reflect.MakeMap(rvt)
106 nv.SetMapIndex(reflect.ValueOf("example"), vv)
108 case reflect.Pointer:
109 nv := reflect.New(rvt.Elem())
110 return FillExample(seen, nv.Elem()).Addr()