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 }