github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/lang/define_map.go (about) 1 package lang 2 3 import ( 4 "strconv" 5 6 "github.com/lmorg/murex/debug" 7 "github.com/lmorg/murex/lang/stdio" 8 "github.com/lmorg/murex/lang/types" 9 ) 10 11 func MapTemplate(dataType string, marshal func(interface{}) ([]byte, error), unmarshal func([]byte, interface{}) error, read stdio.Io, callback func(*stdio.Map)) error { 12 b, err := read.ReadAll() 13 if err != nil { 14 return err 15 } 16 17 var obj interface{} 18 err = unmarshal(b, &obj) 19 if err != nil { 20 return err 21 } 22 23 switch t := obj.(type) { 24 case []interface{}: 25 for i := range t { 26 b, err := marshal(t[i]) 27 if err != nil { 28 return err 29 } 30 callback(&stdio.Map{ 31 Key: strconv.Itoa(i), 32 Value: string(b), 33 DataType: dataType, 34 Last: i != len(t), 35 }) 36 } 37 38 case map[string]string: 39 return mapTemplateStringOfPrimitives(t, callback) 40 case map[string]float64: 41 return mapTemplateStringOfPrimitives(t, callback) 42 case map[string]int: 43 return mapTemplateStringOfPrimitives(t, callback) 44 case map[string]bool: 45 return mapTemplateStringOfPrimitives(t, callback) 46 47 case map[string]interface{}: 48 return mapTemplateStringOfObjects(marshal, t, dataType, callback) 49 50 case map[interface{}]interface{}: 51 return readMapAsInterfaceOfInterfaces(marshal, t, dataType, callback) 52 53 default: 54 if debug.Enabled { 55 panic(t) 56 } 57 } 58 return nil 59 } 60 61 func mapTemplateStringOfPrimitives[V string | int | float64 | bool](t map[string]V, callback func(*stdio.Map)) error { 62 i := 1 63 for key, val := range t { 64 callback(&stdio.Map{ 65 Key: key, 66 Value: val, 67 DataType: types.DataTypeFromInterface(val), 68 Last: i != len(t), 69 }) 70 71 i++ 72 } 73 return nil 74 } 75 76 func mapTemplateStringOfObjects(marshal func(interface{}) ([]byte, error), t map[string]any, dataType string, callback func(*stdio.Map)) error { 77 i := 1 78 for key, val := range t { 79 switch val.(type) { 80 case string, int, float64, bool, nil: 81 callback(&stdio.Map{ 82 Key: key, 83 Value: val, 84 DataType: types.DataTypeFromInterface(val), 85 Last: i != len(t), 86 }) 87 88 default: 89 b, err := marshal(val) 90 if err != nil { 91 return err 92 } 93 94 callback(&stdio.Map{ 95 Key: key, 96 Value: string(b), 97 DataType: dataType, 98 Last: i != len(t), 99 }) 100 } 101 102 i++ 103 } 104 return nil 105 } 106 107 func readMapAsInterfaceOfInterfaces(marshal func(interface{}) ([]byte, error), t map[any]any, dataType string, callback func(*stdio.Map)) error { 108 i := 1 109 for key, val := range t { 110 s, err := types.ConvertGoType(key, types.String) 111 if err != nil { 112 return err 113 } 114 115 switch val.(type) { 116 case string, int, float64, bool, nil: 117 callback(&stdio.Map{ 118 Key: s.(string), 119 Value: val, 120 DataType: types.DataTypeFromInterface(val), 121 Last: i != len(t), 122 }) 123 124 default: 125 b, err := marshal(val) 126 if err != nil { 127 return err 128 } 129 130 callback(&stdio.Map{ 131 Key: s.(string), 132 Value: string(b), 133 DataType: dataType, 134 Last: i != len(t), 135 }) 136 } 137 138 i++ 139 } 140 return nil 141 }