github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/builtins/types/jsonconcat/index.go (about)

     1  package jsonconcat
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"strconv"
     7  
     8  	"github.com/lmorg/murex/lang"
     9  	"github.com/lmorg/murex/lang/types"
    10  )
    11  
    12  func iface2Str(a []interface{}) []string {
    13  	s := make([]string, len(a))
    14  	for i := range a {
    15  		s[i] = fmt.Sprint(a[i])
    16  	}
    17  	return s
    18  }
    19  
    20  func index(p *lang.Process, params []string) error {
    21  	// if it's purely a numeric param then well index by table (ie each row is
    22  	// an array index). Otherwise we'd do our best to splice things into the
    23  	// table
    24  	for i := range params {
    25  		for _, b := range params[i] {
    26  			if b < '0' || b > '9' {
    27  				return indexTable(p, params)
    28  			}
    29  		}
    30  	}
    31  
    32  	return indexObject(p, params)
    33  }
    34  
    35  func indexObject(p *lang.Process, params []string) error {
    36  	lines := make(map[int]bool)
    37  	for i := range params {
    38  		num, err := strconv.Atoi(params[i])
    39  		if err != nil {
    40  			return fmt.Errorf("parameter, `%s`, isn't an integer. %s", params[i], err)
    41  		}
    42  		lines[num] = true
    43  	}
    44  
    45  	var (
    46  		i   int
    47  		err error
    48  	)
    49  
    50  	err = p.Stdin.ReadArray(p.Context, func(b []byte) {
    51  		if lines[i] != p.IsNot {
    52  			_, err = p.Stdout.Writeln(b)
    53  			if err != nil {
    54  				return
    55  			}
    56  		}
    57  		i++
    58  	})
    59  
    60  	return err
    61  }
    62  
    63  func indexTable(p *lang.Process, params []string) error {
    64  	cRecords := make(chan []string, 10)
    65  	status := make(chan error)
    66  
    67  	go func() {
    68  		err1 := p.Stdin.ReadArray(p.Context, func(b []byte) {
    69  			var v []interface{}
    70  			err2 := json.Unmarshal(b, &v)
    71  			if err2 != nil {
    72  				status <- err2
    73  				return
    74  			}
    75  			cRecords <- iface2Str(v)
    76  		})
    77  		if err1 != nil {
    78  			close(cRecords)
    79  			status <- err1
    80  			return
    81  		}
    82  		close(cRecords)
    83  	}()
    84  
    85  	marshaller := func(s []string) []byte {
    86  		b, err3 := lang.MarshalData(p, types.Json, s)
    87  		if err3 != nil {
    88  			close(cRecords)
    89  			status <- err3
    90  		}
    91  		return b
    92  	}
    93  
    94  	go func() {
    95  		err4 := lang.IndexTemplateTable(p, params, cRecords, marshaller)
    96  		status <- err4
    97  	}()
    98  
    99  	return <-status
   100  }