github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/builtins/core/arraytools/map.go (about)

     1  package arraytools
     2  
     3  import (
     4  	"errors"
     5  
     6  	"github.com/lmorg/murex/lang"
     7  	"github.com/lmorg/murex/lang/types"
     8  	"github.com/lmorg/murex/utils/json"
     9  )
    10  
    11  func init() {
    12  	lang.DefineFunction("map", mkmap, types.Json)
    13  }
    14  
    15  func mkmap(p *lang.Process) error {
    16  	p.Stdout.SetDataType(types.Json)
    17  
    18  	blockKey, err := p.Parameters.Block(0)
    19  	if err != nil {
    20  		return err
    21  	}
    22  
    23  	blockValue, err := p.Parameters.Block(1)
    24  	if err != nil {
    25  		return err
    26  	}
    27  
    28  	var aKeys, aValues []string
    29  
    30  	forkKeys := p.Fork(lang.F_NO_STDIN | lang.F_CREATE_STDOUT)
    31  	_, errKeys := forkKeys.Execute(blockKey)
    32  
    33  	forkValues := p.Fork(lang.F_NO_STDIN | lang.F_CREATE_STDOUT)
    34  	_, errValues := forkValues.Execute(blockValue)
    35  
    36  	if errKeys != nil {
    37  		return errKeys
    38  	}
    39  	if errValues != nil {
    40  		return errValues
    41  	}
    42  
    43  	errKeys = forkKeys.Stdout.ReadArray(p.Context, func(b []byte) {
    44  		aKeys = append(aKeys, string(b))
    45  	})
    46  
    47  	errValues = forkValues.Stdout.ReadArray(p.Context, func(b []byte) {
    48  		aValues = append(aValues, string(b))
    49  	})
    50  
    51  	if errKeys != nil {
    52  		return errKeys
    53  	}
    54  	if errValues != nil {
    55  		return errValues
    56  	}
    57  
    58  	if len(aKeys) > len(aValues) {
    59  		return errors.New("there are more keys than values (k > v)")
    60  	}
    61  
    62  	if len(aKeys) < len(aValues) {
    63  		return errors.New("there are more values than keys (v > k)")
    64  	}
    65  
    66  	m := make(map[string]string)
    67  	for i := range aKeys {
    68  		m[aKeys[i]] = aValues[i]
    69  	}
    70  
    71  	b, err := json.Marshal(m, p.Stdout.IsTTY())
    72  	if err != nil {
    73  		return err
    74  	}
    75  	_, err = p.Stdout.Write(b)
    76  	return err
    77  }