jeudi 25 novembre 2021

Implement a struct-to-csv writer in Go

The following code attempt to implement a generic CSV writer for any simple struct. By "simple", I mean field value of the struct are of standard, simple types (int, string etc).

type (
    CSV interface {
        Header() []string
        String([]string) (string, error)
    }
    CSVArray []CSV
)


func CSVOutput(w io.Writer, data CSVArray, cols []string) error {
    if len(data) == 0 {
        return nil
    }
    _, err := fmt.Fprintln(w, data[0].Header())
    if err != nil {
        return err
    }
    for _, d := range data {
        str, err := d.String(cols)
        if err != nil {
            return err
        }
        _, err = fmt.Fprintln(w, str)
        if err != nil {
            return err
        }
    }
    return nil
}

The problem is CSVOutput() does not actually work. e.g.:

var data []Employee //the Employee struct implements CSV interface
CSVOutput(w, data, nil)

Compilation failed: cannot use data (type []Employee) as type CSVArray in argument to CSVOutput

I understand that []CSV is not same as []Employee, as explained here, and many other resources available online.

That said, is it possible to rewrite the CSVOutput() function by using reflection:

func CSVOutput(w io.Writer, data interfac{}, cols []string) error {
    sliceOfIntf = castToSlice(data) //how to do this?
    if !implementedCSV(sliceOfIntf[0]) { //and how to do this?
        return errors.New("not csv")
    }
    ... ...
}




Aucun commentaire:

Enregistrer un commentaire