github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/lang/define_array.go (about) 1 package lang 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/lmorg/murex/lang/stdio" 8 "github.com/lmorg/murex/utils" 9 ) 10 11 // ArrayTemplate is a template function for reading arrays from marshalled data 12 func ArrayTemplate(ctx context.Context, marshal func(interface{}) ([]byte, error), unmarshal func([]byte, interface{}) error, read stdio.Io, callback func([]byte)) error { 13 b, err := read.ReadAll() 14 if err != nil { 15 return err 16 } 17 18 if len(utils.CrLfTrim(b)) == 0 { 19 return nil 20 } 21 22 var v interface{} 23 err = unmarshal(b, &v) 24 25 if err != nil { 26 return err 27 } 28 29 switch v := v.(type) { 30 case string: 31 return readArrayByString(v, callback) 32 33 case []string: 34 return readArrayBySliceString(ctx, v, callback) 35 36 case []interface{}: 37 return readArrayBySliceInterface(ctx, marshal, v, callback) 38 39 case map[string]string: 40 return readArrayByMapStrStr(ctx, v, callback) 41 42 case map[string]interface{}: 43 return readArrayByMapStrIface(ctx, marshal, v, callback) 44 45 case map[interface{}]string: 46 return readArrayByMapIfaceStr(ctx, v, callback) 47 48 case map[interface{}]interface{}: 49 return readArrayByMapIfaceIface(ctx, marshal, v, callback) 50 51 default: 52 jBytes, err := marshal(v) 53 if err != nil { 54 55 return err 56 } 57 58 callback(jBytes) 59 60 return nil 61 } 62 } 63 64 func readArrayByString(v string, callback func([]byte)) error { 65 callback([]byte(v)) 66 67 return nil 68 } 69 70 func readArrayBySliceString(ctx context.Context, v []string, callback func([]byte)) error { 71 for i := range v { 72 select { 73 case <-ctx.Done(): 74 return nil 75 76 default: 77 callback([]byte(v[i])) 78 } 79 } 80 81 return nil 82 } 83 84 func readArrayBySliceInterface(ctx context.Context, marshal func(interface{}) ([]byte, error), v []interface{}, callback func([]byte)) error { 85 if len(v) == 0 { 86 return nil 87 } 88 89 for i := range v { 90 select { 91 case <-ctx.Done(): 92 return nil 93 94 default: 95 switch v := v[i].(type) { 96 case string: 97 callback([]byte(v)) 98 99 case []byte: 100 callback(v) 101 102 default: 103 jBytes, err := marshal(v) 104 if err != nil { 105 return err 106 } 107 callback(jBytes) 108 } 109 } 110 } 111 112 return nil 113 } 114 115 func readArrayByMapIfaceIface(ctx context.Context, marshal func(interface{}) ([]byte, error), v map[interface{}]interface{}, callback func([]byte)) error { 116 for key, val := range v { 117 select { 118 case <-ctx.Done(): 119 return nil 120 121 default: 122 bKey := []byte(fmt.Sprint(key) + ": ") 123 b, err := marshal(val) 124 if err != nil { 125 return err 126 } 127 callback(append(bKey, b...)) 128 } 129 } 130 131 return nil 132 } 133 134 func readArrayByMapStrStr(ctx context.Context, v map[string]string, callback func([]byte)) error { 135 for key, val := range v { 136 select { 137 case <-ctx.Done(): 138 return nil 139 140 default: 141 callback([]byte(key + ": " + val)) 142 } 143 } 144 145 return nil 146 } 147 148 func readArrayByMapStrIface(ctx context.Context, marshal func(interface{}) ([]byte, error), v map[string]interface{}, callback func([]byte)) error { 149 for key, val := range v { 150 select { 151 case <-ctx.Done(): 152 return nil 153 154 default: 155 bKey := []byte(key + ": ") 156 b, err := marshal(val) 157 if err != nil { 158 return err 159 } 160 callback(append(bKey, b...)) 161 } 162 } 163 164 return nil 165 } 166 167 func readArrayByMapIfaceStr(ctx context.Context, v map[interface{}]string, callback func([]byte)) error { 168 for key, val := range v { 169 select { 170 case <-ctx.Done(): 171 return nil 172 173 default: 174 callback([]byte(fmt.Sprint(key) + ": " + val)) 175 } 176 } 177 178 return nil 179 }