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 }