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  }