github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/builtins/types/csv-bad/marshal.go (about) 1 package csvbad 2 3 import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 "os" 8 "sort" 9 "strings" 10 11 "github.com/lmorg/murex/lang" 12 "github.com/lmorg/murex/utils" 13 ) 14 15 func marshal(p *lang.Process, iface interface{}) (b []byte, err error) { 16 w, err := NewParser(nil, p.Config) 17 if err != nil { 18 return 19 } 20 21 switch v := iface.(type) { 22 case []string: 23 for i := range v { 24 s := strings.TrimSpace(v[i]) 25 b = append(b, w.ArrayToCsv([]string{s})...) 26 b = append(b, utils.NewLineByte...) 27 } 28 return 29 30 case [][]string: 31 for i := range v { 32 //s := strings.TrimSpace(v[i]) 33 b = append(b, w.ArrayToCsv(v[i])...) 34 b = append(b, utils.NewLineByte...) 35 } 36 return 37 38 case []interface{}: 39 for i := range v { 40 j, err := json.Marshal(v[i]) 41 s := string(j) 42 if err != nil { 43 s = strings.TrimSpace(fmt.Sprintln(v[i])) 44 } 45 b = append(b, w.ArrayToCsv([]string{s})...) 46 b = append(b, utils.NewLineByte...) 47 } 48 return 49 50 case map[string]string: 51 var headings []string 52 for key := range v { 53 headings = append(headings, key) 54 } 55 sort.Strings(headings) 56 b = w.ArrayToCsv(headings) 57 b = append(b, utils.NewLineByte...) 58 59 records := make([]string, len(headings)) 60 for i := range headings { 61 records[i] = v[headings[i]] 62 } 63 b = append(b, w.ArrayToCsv(records)...) 64 65 return 66 67 case map[string]interface{}: 68 var headings []string 69 for key := range v { 70 headings = append(headings, key) 71 } 72 sort.Strings(headings) 73 b = w.ArrayToCsv(headings) 74 b = append(b, utils.NewLineByte...) 75 76 records := make([]string, len(headings)) 77 for i := range headings { 78 j, err := json.Marshal(v[headings[i]]) 79 s := string(j) 80 if err != nil { 81 s = strings.TrimSpace(fmt.Sprint(v[headings[i]])) 82 } 83 records[i] = s 84 } 85 b = append(b, w.ArrayToCsv(records)...) 86 87 return 88 89 case map[interface{}]string: 90 var headings []string 91 for key := range v { 92 headings = append(headings, fmt.Sprint(key)) 93 } 94 sort.Strings(headings) 95 b = w.ArrayToCsv(headings) 96 b = append(b, utils.NewLineByte...) 97 98 records := make([]string, len(headings)) 99 for i := range headings { 100 records[i] = v[headings[i]] 101 } 102 b = append(b, w.ArrayToCsv(records)...) 103 104 return 105 106 case map[interface{}]interface{}: 107 var headings []string 108 109 for key := range v { 110 headings = append(headings, fmt.Sprint(key)) 111 } 112 sort.Strings(headings) 113 b = w.ArrayToCsv(headings) 114 b = append(b, utils.NewLineByte...) 115 116 records := make([]string, len(headings)) 117 for i := range headings { 118 j, err := json.Marshal(v[headings[i]]) 119 s := string(j) 120 if err != nil { 121 s = strings.TrimSpace(fmt.Sprint(v[headings[i]])) 122 } 123 records[i] = s 124 } 125 b = append(b, w.ArrayToCsv(records)...) 126 return 127 128 case []map[string]string: 129 var headings []string 130 131 for slice := range v { 132 if len(headings) == 0 { 133 for key := range v[slice] { 134 headings = append(headings, key) 135 } 136 sort.Strings(headings) 137 b = w.ArrayToCsv(headings) 138 } 139 140 //order := make(map[string]int) 141 //for i := range headings { 142 // order[headings[i]] = i 143 //} 144 145 records := make([]string, len(headings)) 146 for i := range headings { 147 records[i] = v[slice][headings[i]] 148 } 149 b = append(b, utils.NewLineByte...) 150 b = append(b, w.ArrayToCsv(records)...) 151 } 152 os.Stderr.WriteString("Warning: untested!\n") 153 return b, nil 154 155 case []map[string]interface{}: 156 var headings []string 157 158 for slice := range v { 159 if len(headings) == 0 { 160 for key := range v[slice] { 161 headings = append(headings, key) 162 } 163 sort.Strings(headings) 164 b = w.ArrayToCsv(headings) 165 } 166 167 records := make([]string, len(headings)) 168 for i := range headings { 169 j, err := json.Marshal(v[slice][headings[i]]) 170 s := string(j) 171 if err != nil { 172 s = strings.TrimSpace(fmt.Sprint(v[slice][headings[i]])) 173 } 174 records[i] = s 175 } 176 b = append(b, utils.NewLineByte...) 177 b = append(b, w.ArrayToCsv(records)...) 178 } 179 os.Stderr.WriteString("Warning: untested!\n") 180 return b, nil 181 182 case []map[interface{}]string: 183 var headings []string 184 185 for slice := range v { 186 if len(headings) == 0 { 187 for key := range v[slice] { 188 headings = append(headings, fmt.Sprint(key)) 189 } 190 sort.Strings(headings) 191 b = w.ArrayToCsv(headings) 192 } 193 194 records := make([]string, len(headings)) 195 for i := range headings { 196 j, err := json.Marshal(v[slice][headings[i]]) 197 s := string(j) 198 if err != nil { 199 s = strings.TrimSpace(fmt.Sprint(v[slice][headings[i]])) 200 } 201 records[i] = s 202 } 203 b = append(b, utils.NewLineByte...) 204 b = append(b, w.ArrayToCsv(records)...) 205 } 206 os.Stderr.WriteString("Warning: untested!\n") 207 return b, nil 208 209 case []map[interface{}]interface{}: 210 var headings []string 211 212 for slice := range v { 213 if len(headings) == 0 { 214 for key := range v[slice] { 215 headings = append(headings, fmt.Sprint(key)) 216 } 217 sort.Strings(headings) 218 b = w.ArrayToCsv(headings) 219 } 220 221 records := make([]string, len(headings)) 222 for i := range headings { 223 j, err := json.Marshal(v[slice][headings[i]]) 224 s := string(j) 225 if err != nil { 226 s = strings.TrimSpace(fmt.Sprint(v[slice][headings[i]])) 227 } 228 records[i] = s 229 records[i] = fmt.Sprint(v[slice][headings[i]]) 230 } 231 b = append(b, utils.NewLineByte...) 232 b = append(b, w.ArrayToCsv(records)...) 233 } 234 os.Stderr.WriteString("Warning: untested!\n") 235 return b, nil 236 237 default: 238 err = errors.New("I don't know how to marshal that data into a `csv`. Data possibly too complex?") 239 return 240 } 241 } 242 243 func unmarshal(p *lang.Process) (interface{}, error) { 244 csvReader, err := NewParser(p.Stdin, p.Config) 245 if err != nil { 246 return nil, err 247 } 248 249 table := make([]map[string]string, 0) 250 csvReader.ReadLine(func(recs []string, heads []string) { 251 record := make(map[string]string) 252 for i := range recs { 253 record[heads[i]] = recs[i] 254 } 255 table = append(table, record) 256 }) 257 258 return table, nil 259 }