github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/utils/objectkeys/objectkeys.go (about) 1 package objectkeys 2 3 import ( 4 "context" 5 "fmt" 6 "strconv" 7 8 "github.com/lmorg/murex/lang" 9 ) 10 11 func Recursive(ctx context.Context, path string, v interface{}, separator string, writeString func(string) error, iteration int) error { 12 if iteration == 0 { 13 return nil 14 } 15 16 switch t := v.(type) { 17 case []string: 18 for i := range t { 19 select { 20 case <-ctx.Done(): 21 return nil 22 default: 23 } 24 25 err := writeString(path + separator + strconv.Itoa(i)) 26 if err != nil { 27 return err 28 } 29 } 30 return nil 31 32 case []int: 33 for i := range t { 34 select { 35 case <-ctx.Done(): 36 return nil 37 default: 38 } 39 40 err := writeString(path + separator + strconv.Itoa(i)) 41 if err != nil { 42 return err 43 } 44 } 45 return nil 46 47 case []float64: 48 for i := range t { 49 select { 50 case <-ctx.Done(): 51 return nil 52 default: 53 } 54 55 err := writeString(path + separator + strconv.Itoa(i)) 56 if err != nil { 57 return err 58 } 59 } 60 return nil 61 62 case []uint32: 63 for i := range t { 64 select { 65 case <-ctx.Done(): 66 return nil 67 default: 68 } 69 70 err := writeString(path + separator + strconv.Itoa(i)) 71 if err != nil { 72 return err 73 } 74 } 75 return nil 76 77 case []bool: 78 for i := range t { 79 select { 80 case <-ctx.Done(): 81 return nil 82 default: 83 } 84 85 err := writeString(path + separator + strconv.Itoa(i)) 86 if err != nil { 87 return err 88 } 89 } 90 return nil 91 92 case []interface{}: 93 for i := range t { 94 select { 95 case <-ctx.Done(): 96 return nil 97 default: 98 } 99 100 newPath := path + separator + strconv.Itoa(i) 101 err := writeString(newPath) 102 if err != nil { 103 return err 104 } 105 err = Recursive(ctx, newPath, t[i], separator, writeString, iteration-1) 106 if err != nil { 107 return err 108 } 109 } 110 return nil 111 112 case [][]string: 113 for i := range t { 114 select { 115 case <-ctx.Done(): 116 return nil 117 default: 118 } 119 120 newPath := path + separator + strconv.Itoa(i) 121 err := writeString(newPath) 122 if err != nil { 123 return err 124 } 125 err = Recursive(ctx, newPath, t[i], separator, writeString, iteration-1) 126 if err != nil { 127 return err 128 } 129 } 130 return nil 131 132 case map[string]interface{}: 133 for key := range t { 134 select { 135 case <-ctx.Done(): 136 return nil 137 default: 138 } 139 140 newPath := path + separator + key 141 err := writeString(newPath) 142 if err != nil { 143 return err 144 } 145 err = Recursive(ctx, newPath, t[key], separator, writeString, iteration-1) 146 if err != nil { 147 return err 148 } 149 } 150 return nil 151 152 case map[int]interface{}: 153 for key := range t { 154 select { 155 case <-ctx.Done(): 156 return nil 157 default: 158 } 159 160 newPath := path + separator + strconv.Itoa(key) 161 err := writeString(newPath) 162 if err != nil { 163 return err 164 } 165 err = Recursive(ctx, newPath, t[key], separator, writeString, iteration-1) 166 if err != nil { 167 return err 168 } 169 } 170 return nil 171 172 case map[interface{}]interface{}: 173 for key := range t { 174 select { 175 case <-ctx.Done(): 176 return nil 177 default: 178 } 179 180 newPath := path + separator + fmt.Sprint(key) 181 err := writeString(newPath) 182 if err != nil { 183 return err 184 } 185 err = Recursive(ctx, newPath, t[key], separator, writeString, iteration-1) 186 if err != nil { 187 return err 188 } 189 } 190 return nil 191 192 case string, bool, int, float64, nil, float32, uint, int8, int16, int32, int64, uint8, uint16, uint32, uint64: 193 return nil 194 195 case lang.MxInterface: 196 return Recursive(ctx, path, t.GetValue(), separator, writeString, iteration) 197 198 default: 199 return fmt.Errorf("found %T but no case exists for handling it", t) 200 } 201 }