github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/lang/define_array.go (about)

     1  package lang
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"github.com/lmorg/murex/lang/stdio"
     8  	"github.com/lmorg/murex/utils"
     9  )
    10  
    11  // ArrayTemplate is a template function for reading arrays from marshalled data
    12  func ArrayTemplate(ctx context.Context, marshal func(interface{}) ([]byte, error), unmarshal func([]byte, interface{}) error, read stdio.Io, callback func([]byte)) error {
    13  	b, err := read.ReadAll()
    14  	if err != nil {
    15  		return err
    16  	}
    17  
    18  	if len(utils.CrLfTrim(b)) == 0 {
    19  		return nil
    20  	}
    21  
    22  	var v interface{}
    23  	err = unmarshal(b, &v)
    24  
    25  	if err != nil {
    26  		return err
    27  	}
    28  
    29  	switch v := v.(type) {
    30  	case string:
    31  		return readArrayByString(v, callback)
    32  
    33  	case []string:
    34  		return readArrayBySliceString(ctx, v, callback)
    35  
    36  	case []interface{}:
    37  		return readArrayBySliceInterface(ctx, marshal, v, callback)
    38  
    39  	case map[string]string:
    40  		return readArrayByMapStrStr(ctx, v, callback)
    41  
    42  	case map[string]interface{}:
    43  		return readArrayByMapStrIface(ctx, marshal, v, callback)
    44  
    45  	case map[interface{}]string:
    46  		return readArrayByMapIfaceStr(ctx, v, callback)
    47  
    48  	case map[interface{}]interface{}:
    49  		return readArrayByMapIfaceIface(ctx, marshal, v, callback)
    50  
    51  	default:
    52  		jBytes, err := marshal(v)
    53  		if err != nil {
    54  
    55  			return err
    56  		}
    57  
    58  		callback(jBytes)
    59  
    60  		return nil
    61  	}
    62  }
    63  
    64  func readArrayByString(v string, callback func([]byte)) error {
    65  	callback([]byte(v))
    66  
    67  	return nil
    68  }
    69  
    70  func readArrayBySliceString(ctx context.Context, v []string, callback func([]byte)) error {
    71  	for i := range v {
    72  		select {
    73  		case <-ctx.Done():
    74  			return nil
    75  
    76  		default:
    77  			callback([]byte(v[i]))
    78  		}
    79  	}
    80  
    81  	return nil
    82  }
    83  
    84  func readArrayBySliceInterface(ctx context.Context, marshal func(interface{}) ([]byte, error), v []interface{}, callback func([]byte)) error {
    85  	if len(v) == 0 {
    86  		return nil
    87  	}
    88  
    89  	for i := range v {
    90  		select {
    91  		case <-ctx.Done():
    92  			return nil
    93  
    94  		default:
    95  			switch v := v[i].(type) {
    96  			case string:
    97  				callback([]byte(v))
    98  
    99  			case []byte:
   100  				callback(v)
   101  
   102  			default:
   103  				jBytes, err := marshal(v)
   104  				if err != nil {
   105  					return err
   106  				}
   107  				callback(jBytes)
   108  			}
   109  		}
   110  	}
   111  
   112  	return nil
   113  }
   114  
   115  func readArrayByMapIfaceIface(ctx context.Context, marshal func(interface{}) ([]byte, error), v map[interface{}]interface{}, callback func([]byte)) error {
   116  	for key, val := range v {
   117  		select {
   118  		case <-ctx.Done():
   119  			return nil
   120  
   121  		default:
   122  			bKey := []byte(fmt.Sprint(key) + ": ")
   123  			b, err := marshal(val)
   124  			if err != nil {
   125  				return err
   126  			}
   127  			callback(append(bKey, b...))
   128  		}
   129  	}
   130  
   131  	return nil
   132  }
   133  
   134  func readArrayByMapStrStr(ctx context.Context, v map[string]string, callback func([]byte)) error {
   135  	for key, val := range v {
   136  		select {
   137  		case <-ctx.Done():
   138  			return nil
   139  
   140  		default:
   141  			callback([]byte(key + ": " + val))
   142  		}
   143  	}
   144  
   145  	return nil
   146  }
   147  
   148  func readArrayByMapStrIface(ctx context.Context, marshal func(interface{}) ([]byte, error), v map[string]interface{}, callback func([]byte)) error {
   149  	for key, val := range v {
   150  		select {
   151  		case <-ctx.Done():
   152  			return nil
   153  
   154  		default:
   155  			bKey := []byte(key + ": ")
   156  			b, err := marshal(val)
   157  			if err != nil {
   158  				return err
   159  			}
   160  			callback(append(bKey, b...))
   161  		}
   162  	}
   163  
   164  	return nil
   165  }
   166  
   167  func readArrayByMapIfaceStr(ctx context.Context, v map[interface{}]string, callback func([]byte)) error {
   168  	for key, val := range v {
   169  		select {
   170  		case <-ctx.Done():
   171  			return nil
   172  
   173  		default:
   174  			callback([]byte(fmt.Sprint(key) + ": " + val))
   175  		}
   176  	}
   177  
   178  	return nil
   179  }