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