Documentation
¶
Overview ¶
Package csvplus marshals/unmarshals CSV data directly from/to slice of structs, types are converted to those matching the fields on the struct. Layout strings can be provided via struct tags for time.Time fields.
Index ¶
- func Marshal(v interface{}) ([]byte, error)
- func MarshalWithoutHeader(v interface{}) ([]byte, error)
- func MarshalWriter(v interface{}, w io.Writer) error
- func Unmarshal(data []byte, v interface{}) error
- func UnmarshalReader(r io.Reader, v interface{}) error
- func UnmarshalWithoutHeader(data []byte, v interface{}) error
- type Decoder
- type Encoder
- type Marshaler
- type UnmarhsalError
- type Unmarshaler
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Marshal ¶
Marshal marshals v into csv data.
Example ¶
package main import ( "fmt" "time" "github.com/j0hnsmith/csvplus" ) func main() { type Item struct { First string `csvplus:"first"` Second int `csvplus:"second"` Third *bool `csvplus:"third"` Fourth *time.Time `csvplus:"fourth" csvplusFormat:"2006-01"` } tm, _ := time.Parse("2006-01", "2000-01") f := false items := []Item{ {"a", 1, nil, &tm}, {"b", 2, &f, nil}, } data, err := csvplus.Marshal(&items) if err != nil { panic(err) } fmt.Println(string(data)) }
Output: first,second,third,fourth a,1,,2000-01 b,2,false,
func MarshalWithoutHeader ¶
MarshalWithoutHeader writes csv data without a header row.
func MarshalWriter ¶
MarshalWriter marshals v into the given writer.
func Unmarshal ¶
Unmarshal parses the csv encoded data and stores the result in the slice pointed to by v. The number of records in row of the csv data must match the number of exported fields in the struct. For common types (eg int, bool, float64...) a standard conversion from a string is applied. If a type implements the Unmarshaler interface, that will be used to unmarshal the record instead. This function assumes the csv data has a header row (which is skipped), see the Decoder type if your data doesn't have a header row.
Example ¶
package main import ( "fmt" "time" "github.com/j0hnsmith/csvplus" ) func main() { type Item struct { First string `csvplus:"first"` Second int `csvplus:"second"` Third *bool `csvplus:"third"` Forth *time.Time `csvplus:"forth" csvplusFormat:"2006-01"` } // The CSV data we want to unmarshal. // If your data is in a *File (or other io.Reader), use UnmarshalReader(). data := []byte("first,second,third,forth\na,1,,2000-01\nb,2,f,") var items []Item err := csvplus.Unmarshal(data, &items) if err != nil { panic(err) } fmt.Printf("%+v\n", items[0]) fmt.Printf("{First:%s Second:%d Third:%t (dereferenced) Forth:%s}\n", items[1].First, items[1].Second, *items[1].Third, items[1].Forth) }
Output: {First:a Second:1 Third:<nil> Forth:2000-01-01 00:00:00 +0000 UTC} {First:b Second:2 Third:false (dereferenced) Forth:<nil>}
func UnmarshalReader ¶
UnmarshalReader is the same as Unmarshal but takes it's input data from an io.Reader.
func UnmarshalWithoutHeader ¶
UnmarshalWithoutHeader is used to unmarshal csv data that doesn't have a header row.
Types ¶
type Decoder ¶
type Decoder struct {
// contains filtered or unexported fields
}
A Decoder reads and decodes CSV records from an input stream. Useful if your data doesn't have a header row.
func NewDecoder ¶
NewDecoder reads and decodes CSV records from r.
func (*Decoder) SetCSVReader ¶
SetCSVReader allows for using a custom csv.Reader (eg | field separator instead of ,).
Example ¶
package main import ( "bytes" "encoding/csv" "fmt" "time" "github.com/j0hnsmith/csvplus" ) func main() { type Item struct { Name string `csvplus:"name"` Timestamp *time.Time `csvplus:"when" csvplusFormat:"2006-01"` } data := []byte("name|when\nRob|1999-11\nRuss|") // create a *csv.Reader r := csv.NewReader(bytes.NewReader(data)) // modify to get the required functionality, in this case '|' separated fields r.Comma = '|' dec := csvplus.NewDecoder(bytes.NewReader(data)) // set the csv reader to the custom reader dec.SetCSVReader(r) var items []Item err := dec.Decode(&items) if err != nil { panic(err) } fmt.Printf("{%s %s}\n", items[0].Name, items[0].Timestamp) fmt.Printf("{%s %+v}\n", items[1].Name, items[1].Timestamp) }
Output: {Rob 1999-11-01 00:00:00 +0000 UTC} {Russ <nil>}
type Encoder ¶
type Encoder struct {
// contains filtered or unexported fields
}
An Encoder writes csv data from a list of struct.
func (*Encoder) SetCSVWriter ¶
SetCSVWriter allows for using a csv.Writer with custom config (eg | field separator instead of ,).
type Marshaler ¶
Marshaler is the interface implemented by types that can marshal a csv value (string) of themselves.
type UnmarhsalError ¶
func (UnmarhsalError) Error ¶
func (um UnmarhsalError) Error() string
type Unmarshaler ¶
Unmarshaler is the interface implemented by types that can unmarshal a csv record of themselves.
Example ¶
package main import ( "fmt" "time" "github.com/j0hnsmith/csvplus" ) // YesNoBool is an example field that implements Unmarhsaler, it's used in an example. type YesNoBool bool // UnmarshalCSV is an implementation of the Unmarshaller interface, converts a string record to a native // value for this type. func (ynb *YesNoBool) UnmarshalCSV(s string) error { if ynb == nil { return fmt.Errorf("cannot unmarshal into nil pointer") } switch s { case "yes": *ynb = YesNoBool(true) return nil case "no": *ynb = YesNoBool(false) return nil case "": *ynb = YesNoBool(false) return nil } return fmt.Errorf("unable to convert %s to bool", s) } func (ynb *YesNoBool) MarshalCSV() ([]byte, error) { if ynb == nil || !*ynb { return []byte("no"), nil } return []byte("yes"), nil } func main() { // type YesNoBool bool // func (ynb *YesNoBool) UnmarshalCSV(s string) error { // if ynb == nil { // return fmt.Errorf("cannot unmarshal into nil pointer") // } // switch s { // case "yes": // *ynb = YesNoBool(true) // return nil // case "no": // *ynb = YesNoBool(false) // return nil // case "": // *ynb = YesNoBool(false) // custom zero value // return nil // } // return fmt.Errorf("unable to convert %s to bool", s) // } type Item struct { Name string `csvplus:"name"` Seen *YesNoBool `csvplus:"seen"` // custom type that implements Unmarshaler Agreed *YesNoBool `csvplus:"agreed"` // custom type that implements Unmarshaler Timestamp *time.Time `csvplus:"when" csvplusFormat:"2006-01"` } // The CSV data we want to unmarshal, note the custom format. data := []byte("name,seen,agreed,when\nRob,yes,yes,1999-11\nRuss,,no,") var items []Item err := csvplus.Unmarshal(data, &items) if err != nil { panic(err) } fmt.Printf("{%s %t (dereferenced) %t %s}\n", items[0].Name, *items[0].Seen, *items[0].Agreed, items[0].Timestamp) fmt.Printf("{%s %+v %t %+v}\n", items[1].Name, *items[1].Seen, *items[1].Agreed, items[1].Timestamp) }
Output: {Rob true (dereferenced) true 1999-11-01 00:00:00 +0000 UTC} {Russ false false <nil>}