github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/docs/apis/lang.ArrayTemplate.md (about) 1 # `lang.ArrayTemplate()` (template API) 2 3 > Unmarshals a data type into a Go struct and returns the results as an array 4 5 ## Description 6 7 This is a template API you can use for your custom data types to wrap around an 8 existing Go marshaller and return a Murex array which is consistent with 9 other structures such as nested JSON or YAML documents. 10 11 It should only be called from `ReadArray()` functions. 12 13 Because `lang.ArrayTemplate()` relies on a marshaller, it means any types that 14 rely on this API are not going to be stream-able. 15 16 17 18 ## Examples 19 20 Example calling `lang.ArrayTemplate()` function: 21 22 ```go 23 package json 24 25 import ( 26 "context" 27 28 "github.com/lmorg/murex/lang" 29 "github.com/lmorg/murex/lang/stdio" 30 "github.com/lmorg/murex/utils/json" 31 ) 32 33 func readArray(ctx context.Context, read stdio.Io, callback func([]byte)) error { 34 // Create a marshaller function to pass to ArrayTemplate 35 marshaller := func(v interface{}) ([]byte, error) { 36 return json.Marshal(v, read.IsTTY()) 37 } 38 39 return lang.ArrayTemplate(ctx, marshaller, json.Unmarshal, read, callback) 40 } 41 ``` 42 43 ## Detail 44 45 ### API Source: 46 47 ```go 48 package lang 49 50 import ( 51 "context" 52 "fmt" 53 54 "github.com/lmorg/murex/lang/stdio" 55 "github.com/lmorg/murex/utils" 56 ) 57 58 // ArrayTemplate is a template function for reading arrays from marshalled data 59 func ArrayTemplate(ctx context.Context, marshal func(interface{}) ([]byte, error), unmarshal func([]byte, interface{}) error, read stdio.Io, callback func([]byte)) error { 60 b, err := read.ReadAll() 61 if err != nil { 62 return err 63 } 64 65 if len(utils.CrLfTrim(b)) == 0 { 66 return nil 67 } 68 69 var v interface{} 70 err = unmarshal(b, &v) 71 72 if err != nil { 73 return err 74 } 75 76 switch v := v.(type) { 77 case string: 78 return readArrayByString(v, callback) 79 80 case []string: 81 return readArrayBySliceString(ctx, v, callback) 82 83 case []interface{}: 84 return readArrayBySliceInterface(ctx, marshal, v, callback) 85 86 case map[string]string: 87 return readArrayByMapStrStr(ctx, v, callback) 88 89 case map[string]interface{}: 90 return readArrayByMapStrIface(ctx, marshal, v, callback) 91 92 case map[interface{}]string: 93 return readArrayByMapIfaceStr(ctx, v, callback) 94 95 case map[interface{}]interface{}: 96 return readArrayByMapIfaceIface(ctx, marshal, v, callback) 97 98 default: 99 jBytes, err := marshal(v) 100 if err != nil { 101 102 return err 103 } 104 105 callback(jBytes) 106 107 return nil 108 } 109 } 110 111 func readArrayByString(v string, callback func([]byte)) error { 112 callback([]byte(v)) 113 114 return nil 115 } 116 117 func readArrayBySliceString(ctx context.Context, v []string, callback func([]byte)) error { 118 for i := range v { 119 select { 120 case <-ctx.Done(): 121 return nil 122 123 default: 124 callback([]byte(v[i])) 125 } 126 } 127 128 return nil 129 } 130 131 func readArrayBySliceInterface(ctx context.Context, marshal func(interface{}) ([]byte, error), v []interface{}, callback func([]byte)) error { 132 if len(v) == 0 { 133 return nil 134 } 135 136 for i := range v { 137 select { 138 case <-ctx.Done(): 139 return nil 140 141 default: 142 switch v := v[i].(type) { 143 case string: 144 callback([]byte(v)) 145 146 case []byte: 147 callback(v) 148 149 default: 150 jBytes, err := marshal(v) 151 if err != nil { 152 return err 153 } 154 callback(jBytes) 155 } 156 } 157 } 158 159 return nil 160 } 161 162 func readArrayByMapIfaceIface(ctx context.Context, marshal func(interface{}) ([]byte, error), v map[interface{}]interface{}, callback func([]byte)) error { 163 for key, val := range v { 164 select { 165 case <-ctx.Done(): 166 return nil 167 168 default: 169 bKey := []byte(fmt.Sprint(key) + ": ") 170 b, err := marshal(val) 171 if err != nil { 172 return err 173 } 174 callback(append(bKey, b...)) 175 } 176 } 177 178 return nil 179 } 180 181 func readArrayByMapStrStr(ctx context.Context, v map[string]string, callback func([]byte)) error { 182 for key, val := range v { 183 select { 184 case <-ctx.Done(): 185 return nil 186 187 default: 188 callback([]byte(key + ": " + val)) 189 } 190 } 191 192 return nil 193 } 194 195 func readArrayByMapStrIface(ctx context.Context, marshal func(interface{}) ([]byte, error), v map[string]interface{}, callback func([]byte)) error { 196 for key, val := range v { 197 select { 198 case <-ctx.Done(): 199 return nil 200 201 default: 202 bKey := []byte(key + ": ") 203 b, err := marshal(val) 204 if err != nil { 205 return err 206 } 207 callback(append(bKey, b...)) 208 } 209 } 210 211 return nil 212 } 213 214 func readArrayByMapIfaceStr(ctx context.Context, v map[interface{}]string, callback func([]byte)) error { 215 for key, val := range v { 216 select { 217 case <-ctx.Done(): 218 return nil 219 220 default: 221 callback([]byte(fmt.Sprint(key) + ": " + val)) 222 } 223 } 224 225 return nil 226 } 227 ``` 228 229 ## Parameters 230 231 1. `func(interface{}) ([]byte, error)`: data type's marshaller 232 2. `func([]byte, interface{}) error`: data type's unmarshaller 233 3. `stdio.Io`: stream to read from (eg STDIN) 234 4. `func([]byte)`: callback function to write each array element 235 236 ## See Also 237 238 * [apis/`ReadArray()` (type)](../apis/ReadArray.md): 239 Read from a data type one array element at a time 240 * [apis/`ReadArrayWithType()` (type)](../apis/ReadArrayWithType.md): 241 Read from a data type one array element at a time and return the elements contents and data type 242 * [apis/`ReadIndex()` (type)](../apis/ReadIndex.md): 243 Data type handler for the index, `[`, builtin 244 * [apis/`ReadMap()` (type)](../apis/ReadMap.md): 245 Treat data type as a key/value structure and read its contents 246 * [apis/`ReadNotIndex()` (type)](../apis/ReadNotIndex.md): 247 Data type handler for the bang-prefixed index, `: 249 Write a data type, one array element at a time 250 * [apis/`lang.IndexTemplateObject()` (template API)](../apis/lang.IndexTemplateObject.md): 251 Returns element(s) from a data structure 252 * [apis/`lang.IndexTemplateTable()` (template API)](../apis/lang.IndexTemplateTable.md): 253 Returns element(s) from a table 254 255 <hr/> 256 257 This document was generated from [lang/stdio/interface_doc.yaml](https://github.com/lmorg/murex/blob/master/lang/stdio/interface_doc.yaml).