|
| 1 | +package simpleserializer |
| 2 | + |
| 3 | +import ( |
| 4 | + "bytes" |
| 5 | + "fmt" |
| 6 | + "reflect" |
| 7 | + "encoding/csv" |
| 8 | + "encoding/json" |
| 9 | + "strings" |
| 10 | +) |
| 11 | + |
| 12 | +import ( |
| 13 | + "gopkg.in/yaml.v2" |
| 14 | + "github.com/pkg/errors" |
| 15 | + "github.com/BurntSushi/toml" |
| 16 | +) |
| 17 | + |
| 18 | +func Serialize(input interface{}, format string) (string, error) { |
| 19 | + output := "" |
| 20 | + |
| 21 | + if format == "csv" { |
| 22 | + s := reflect.ValueOf(input) |
| 23 | + if s.Kind() != reflect.Slice { |
| 24 | + return "", errors.New("Input is not of kind slice.") |
| 25 | + } |
| 26 | + if s.Len() > 0 { |
| 27 | + first := s.Index(0).Type() |
| 28 | + if first.Kind() == reflect.Ptr { |
| 29 | + first = first.Elem() |
| 30 | + } |
| 31 | + rows := make([][]string, 0) |
| 32 | + header := make([]string, first.NumField()) |
| 33 | + for i := 0; i < first.NumField(); i++ { |
| 34 | + if tag := first.Field(i).Tag.Get("csv"); len(tag) > 0 { |
| 35 | + header[i] = tag |
| 36 | + } else { |
| 37 | + header[i] = first.Field(i).Name |
| 38 | + } |
| 39 | + } |
| 40 | + for i := 0; i < s.Len(); i++ { |
| 41 | + rows = append(rows, make([]string, first.NumField())) |
| 42 | + for j := 0; j < len(header); j++ { |
| 43 | + ft := first.Field(j).Type |
| 44 | + switch { |
| 45 | + case ft == reflect.TypeOf(""): |
| 46 | + rows[i][j] = s.Index(i).Elem().Field(j).String() |
| 47 | + case ft == reflect.TypeOf([]string{}): |
| 48 | + slice_as_strings := s.Index(i).Elem().Field(j).Interface().([]string) |
| 49 | + rows[i][j] = strings.Join(slice_as_strings, ",") |
| 50 | + default: |
| 51 | + rows[i][j] = "" |
| 52 | + } |
| 53 | + } |
| 54 | + } |
| 55 | + buf := new(bytes.Buffer) |
| 56 | + w := csv.NewWriter(buf) |
| 57 | + w.Write(header) |
| 58 | + w.WriteAll(rows) |
| 59 | + output = buf.String() |
| 60 | + } |
| 61 | + } else if format == "json" { |
| 62 | + text, err := json.Marshal(input) |
| 63 | + if err != nil { |
| 64 | + return "", err |
| 65 | + } |
| 66 | + output = string(text) |
| 67 | + } else if format == "jsonl" { |
| 68 | + s := reflect.ValueOf(input) |
| 69 | + if s.Kind() != reflect.Slice { |
| 70 | + return "", errors.New("Input is not of kind slice.") |
| 71 | + } |
| 72 | + for i := 0; i < s.Len(); i++ { |
| 73 | + text, err := json.Marshal(s.Index(i).Interface()) |
| 74 | + if err != nil { |
| 75 | + return "", err |
| 76 | + } |
| 77 | + output += string(text) |
| 78 | + if i < s.Len() -1 { |
| 79 | + output += "\n" |
| 80 | + } |
| 81 | + } |
| 82 | + } else if format == "toml" { |
| 83 | + buf := new(bytes.Buffer) |
| 84 | + if err := toml.NewEncoder(buf).Encode(input); err != nil { |
| 85 | + return "", errors.New(fmt.Sprintf("Error encoding TOML: %s", err)) |
| 86 | + } |
| 87 | + output = buf.String() |
| 88 | + } else if format == "yaml" { |
| 89 | + y, err := yaml.Marshal(input) |
| 90 | + if err != nil { |
| 91 | + return "", err |
| 92 | + } |
| 93 | + output = string(y) |
| 94 | + } |
| 95 | + return output, nil |
| 96 | +} |
0 commit comments