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

     1  package csv
     2  
     3  import (
     4  	"bytes"
     5  	enc "encoding/csv"
     6  	"fmt"
     7  	"io"
     8  	"os"
     9  	"reflect"
    10  
    11  	"github.com/lmorg/murex/lang"
    12  	"github.com/lmorg/murex/lang/types"
    13  )
    14  
    15  func marshal(p *lang.Process, iface interface{}) ([]byte, error) {
    16  	var b []byte
    17  	buf := bytes.NewBuffer(b)
    18  	w := enc.NewWriter(buf)
    19  
    20  	//if term.
    21  
    22  	separator, err := p.Config.Get("csv", "separator", types.String)
    23  	if err != nil {
    24  		return nil, err
    25  	}
    26  	if len(separator.(string)) != 0 {
    27  		w.Comma = []rune(separator.(string))[0]
    28  	}
    29  
    30  	switch v := iface.(type) {
    31  	case []string:
    32  		for i := range v {
    33  			err = w.Write([]string{v[i]})
    34  			if err != nil {
    35  				return buf.Bytes(), err
    36  			}
    37  		}
    38  		break
    39  
    40  	case [][]string:
    41  		for i := range v {
    42  			err = w.Write(v[i])
    43  			if err != nil {
    44  				return buf.Bytes(), err
    45  			}
    46  		}
    47  		break
    48  
    49  	case []interface{}:
    50  		if len(v) == 0 {
    51  			w.Flush()
    52  			return buf.Bytes(), w.Error()
    53  		}
    54  
    55  		if reflect.TypeOf(v[0]).Kind() != reflect.Map {
    56  			for i := range v {
    57  				err = w.Write([]string{fmt.Sprint(v[i])})
    58  				if err != nil {
    59  					return buf.Bytes(), err
    60  				}
    61  			}
    62  			break
    63  		}
    64  
    65  		err = types.MapToTable(v, func(s []string) error { return w.Write(s) })
    66  		if err != nil {
    67  			return nil, err
    68  		}
    69  
    70  	default:
    71  		err = fmt.Errorf("cannot marshal %T data into a `%s`", v, typeName)
    72  		return buf.Bytes(), err
    73  	}
    74  
    75  	var table []byte
    76  	if os.Getenv("MXTTY") == "true" {
    77  		table = []byte("\x1b_begin;table;{\"Format\":\"csv\"}\x1b\\")
    78  	}
    79  	table = append(table, buf.Bytes()...)
    80  	if os.Getenv("MXTTY") == "true" {
    81  		table = append(table, []byte("\x1b_end;table\x1b\\")...)
    82  	}
    83  
    84  	w.Flush()
    85  	return table, w.Error()
    86  }
    87  
    88  func unmarshal(p *lang.Process) (interface{}, error) {
    89  	csvReader := enc.NewReader(p.Stdin)
    90  	csvReader.TrimLeadingSpace = true
    91  
    92  	v, err := p.Config.Get("csv", "separator", types.String)
    93  	if err != nil {
    94  		return nil, err
    95  	}
    96  	if len(v.(string)) != 0 {
    97  		csvReader.Comma = rune(v.(string)[0])
    98  	}
    99  
   100  	v, err = p.Config.Get("csv", "comment", types.String)
   101  	if err != nil {
   102  		return nil, err
   103  	}
   104  	if len(v.(string)) != 0 {
   105  		csvReader.Comment = rune(v.(string)[0])
   106  	}
   107  
   108  	var table [][]string
   109  
   110  	for {
   111  		record, err := csvReader.Read()
   112  		if record == nil && err == io.EOF {
   113  			break
   114  		}
   115  		table = append(table, record)
   116  	}
   117  
   118  	return table, nil
   119  }