github.com/viant/toolbox@v0.34.5/data/udf/conversion.go (about) 1 package udf 2 3 import ( 4 "fmt" 5 "github.com/viant/toolbox" 6 "github.com/viant/toolbox/data" 7 "gopkg.in/yaml.v2" 8 "strings" 9 ) 10 11 //AsInt converts source into int 12 func AsInt(source interface{}, state data.Map) (interface{}, error) { 13 return toolbox.ToInt(source) 14 } 15 16 //AsInt converts source into int 17 func AsString(source interface{}, state data.Map) (interface{}, error) { 18 isNonByteSlice := toolbox.IsSlice(source) 19 if isNonByteSlice { 20 if _, isByteArray := source.([]byte); isByteArray { 21 isNonByteSlice = false 22 } 23 } 24 if isNonByteSlice || toolbox.IsMap(source) || toolbox.IsStruct(source) { 25 text, err := toolbox.AsJSONText(source) 26 if err == nil { 27 return text, nil 28 } 29 } 30 if toolbox.IsNumber(source) { 31 source, _ = AsNumber(source, state) 32 } 33 34 return toolbox.AsString(source), nil 35 } 36 37 38 //Lower converts string to lower case 39 func ToLower(source interface{}, state data.Map) (interface{}, error) { 40 return strings.ToLower(toolbox.AsString(source)), nil 41 } 42 43 44 //Lower converts string to upper case 45 func ToUpper(source interface{}, state data.Map) (interface{}, error) { 46 return strings.ToUpper(toolbox.AsString(source)), nil 47 } 48 49 50 51 //AsFloat converts source into float64 52 func AsFloat(source interface{}, state data.Map) (interface{}, error) { 53 return toolbox.AsFloat(source), nil 54 } 55 56 //AsFloat32 converts source into float32 57 func AsFloat32(source interface{}, state data.Map) (interface{}, error) { 58 return float32(toolbox.AsFloat(source)), nil 59 } 60 61 //AsFloat32 converts source into float32 62 func AsFloat32Ptr(source interface{}, state data.Map) (interface{}, error) { 63 result := float32(toolbox.AsFloat(source)) 64 return &result, nil 65 } 66 67 //AsBool converts source into bool 68 func AsBool(source interface{}, state data.Map) (interface{}, error) { 69 return toolbox.AsBoolean(source), nil 70 } 71 72 //AsMap converts source into map 73 func AsMap(source interface{}, state data.Map) (interface{}, error) { 74 if source == nil || toolbox.IsMap(source) { 75 return source, nil 76 } 77 source = convertToTextIfNeeded(source) 78 if text, ok := source.(string); ok { 79 text = strings.TrimSpace(text) 80 aMap := map[string]interface{}{} 81 if strings.HasPrefix(text, "{") || strings.HasSuffix(text, "}") { 82 if err := toolbox.NewJSONDecoderFactory().Create(strings.NewReader(text)).Decode(&aMap); err != nil { 83 return nil, err 84 } 85 } 86 if err := yaml.NewDecoder(strings.NewReader(toolbox.AsString(source))).Decode(&aMap); err != nil { 87 return nil, err 88 } 89 return toolbox.NormalizeKVPairs(aMap) 90 } 91 return toolbox.ToMap(source) 92 } 93 94 //AsCollection converts source into a slice 95 func AsCollection(source interface{}, state data.Map) (interface{}, error) { 96 if source == nil || toolbox.IsSlice(source) { 97 return source, nil 98 } 99 source = convertToTextIfNeeded(source) 100 if text, ok := source.(string); ok { 101 text = strings.TrimSpace(text) 102 if strings.HasPrefix(text, "[") || strings.HasSuffix(text, "[") { 103 aSlice := []interface{}{} 104 if err := toolbox.NewJSONDecoderFactory().Create(strings.NewReader(text)).Decode(&aSlice); err != nil { 105 return nil, err 106 } 107 } 108 var aSlice interface{} 109 if err := yaml.NewDecoder(strings.NewReader(toolbox.AsString(source))).Decode(&aSlice); err != nil { 110 return nil, err 111 } 112 return toolbox.NormalizeKVPairs(aSlice) 113 } 114 return nil, fmt.Errorf("unable convert to slice, unsupported type: %T", source) 115 } 116 117 //AsData converts source into map or slice 118 func AsData(source interface{}, state data.Map) (interface{}, error) { 119 if source == nil || toolbox.IsMap(source) || toolbox.IsSlice(source) { 120 return source, nil 121 } 122 var aData interface{} 123 source = convertToTextIfNeeded(source) 124 if text, ok := source.(string); ok { 125 text = strings.TrimSpace(text) 126 if strings.HasPrefix(text, "[") || strings.HasSuffix(text, "[") || strings.HasPrefix(text, "{") || strings.HasSuffix(text, "}") { 127 if err := toolbox.NewJSONDecoderFactory().Create(strings.NewReader(text)).Decode(&aData); err != nil { 128 return nil, err 129 } 130 } 131 if err := yaml.NewDecoder(strings.NewReader(toolbox.AsString(source))).Decode(&aData); err != nil { 132 return nil, err 133 } 134 return toolbox.NormalizeKVPairs(aData) 135 } 136 return source, nil 137 } 138 139 func convertToTextIfNeeded(data interface{}) interface{} { 140 if data == nil { 141 return data 142 } 143 if bs, ok := data.([]byte); ok { 144 return string(bs) 145 } 146 return data 147 } 148 149 //AsJSON converts source to JSON 150 func AsJSON(source interface{}, state data.Map) (interface{}, error) { 151 return toolbox.AsIndentJSONText(source) 152 } 153 154 //Type returns source type 155 func Type(source interface{}, state data.Map) (interface{}, error) { 156 return fmt.Printf("%T", source) 157 } 158 159 //AsStringMap returns map[string]string 160 func AsStringMap(source interface{}, state data.Map) (interface{}, error) { 161 if source == nil && !toolbox.IsMap(source) { 162 return nil, fmt.Errorf("not a map") 163 } 164 var result = make(map[string]string) 165 for k, v := range toolbox.AsMap(source) { 166 result[k] = toolbox.AsString(v) 167 } 168 return result, nil 169 } 170 171