Documentation ¶
Overview ¶
Package csvcoder decodes Go types from CSV records using struct tags, similar to encoding/csv and encoding/xml packages in the standard library.
Like the standard library packages for JSON and XML encoding, this package uses tags on struct fields to specify the correspondence of a CSV column with a struct field. See the examples for full usage, but to get a sense of how csvcoder works, observe the following structure definition:
type mass float64 type species struct { Name string `csv:"name"` EstimatedPopulation int `csv:"population_estimate"` Mass mass `csv:"weight_kg"` } csvcoder.RegisterRowStruct(reflect.TypeOf(&species{}))
Unlike the standard library packages, this package uses textcoder for decoding textual values, allowing any package to provide a decoder for a given type rather than using methods of the type.
Example (ARowParsing) ¶
package main import ( "fmt" "reflect" "github.com/google/xtoproto/csvcoder" ) func main() { type mass float64 type species struct { Name string `csv:"name"` Mass mass `csv:"weight_kg"` } csvcoder.RegisterRowStruct(reflect.TypeOf(&species{})) redwood := &species{} err := csvcoder.ParseRow( csvcoder.NewRow( []string{"Redwood", "1200000"}, csvcoder.NewHeader([]string{"name", "weight_kg"}), csvcoder.RowNumber(10), "example.csv"), redwood) fmt.Printf("error: %v\n", err != nil) fmt.Printf("record: name = %q, mass = %f", redwood.Name, redwood.Mass) }
Output: error: false record: name = "Redwood", mass = 1200000.000000
Example (BFileParsing) ¶
package main import ( "encoding/csv" "fmt" "reflect" "strings" "github.com/google/xtoproto/csvcoder" ) func main() { type mass float64 type species struct { Name string `csv:"name"` Mass float64 `csv:"weight_kg"` } csvcoder.RegisterRowStruct(reflect.TypeOf(&species{})) inputReader := csv.NewReader(strings.NewReader(`name,weight_kg Redwood,1200000 "Blue whale",200000 `)) fp, err := csvcoder.NewFileParser(inputReader, "in-memory.csv", &species{}) if err != nil { fmt.Printf("NewFileParser error: %v", err) return } if err := fp.ReadAll(func(i interface{}) error { rec := i.(*species) fmt.Printf("record: name = %q, mass = %f\n", rec.Name, rec.Mass) return nil }); err != nil { fmt.Printf("ReadAll error: %v\n", err) } }
Output: record: name = "Redwood", mass = 1200000.000000 record: name = "Blue whale", mass = 200000.000000
Index ¶
- func ParseCell(ctx *CellContext, value string, dst interface{}) error
- func ParseRow(row *Row, destination interface{}) error
- func RegisterRowStruct(t reflect.Type, opt ...RegisterOption)
- func SafeRegisterRowStruct(t reflect.Type, opt ...RegisterOption) error
- type CellContext
- type ColumnNumber
- type FileParser
- type Header
- type RegisterOption
- type Row
- type RowNumber
- type RowReader
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ParseCell ¶
func ParseCell(ctx *CellContext, value string, dst interface{}) error
ParseCell parses a single CSV cell's textual value into dst.
func ParseRow ¶
ParseRow returns an error if the row fails to parse.
If the destination object has a `ParseCSVRow(*Row) error` method, that method will be called on the destination object.
func RegisterRowStruct ¶
func RegisterRowStruct(t reflect.Type, opt ...RegisterOption)
RegisterRowStruct registers a struct type T that can be encoded as a CSV row.
Each public field of the struct definition will be examined and treated as follows:
1. If the field has a `csv-skip` tag, it will not be parsed.
2. If the field has a `csv` tag, that tag will be treated as the name of the CSV column for the field. If the tag is absent, the column name used will be the name of the field.
3. Let FT be the Go type of the field. If there is a registered decoder for *FT, that decoder will be used to decode the string value of the field with the name from step 2 into the field of a row being parsed. If there is no registered decoder for *FT, RegisterRowStruct will panic and SafeRegisterRowStruct returns an error.
Example ¶
type Pet struct { Name string `csv:"pet-name"` Internal string `csv-skip:""` WeightPounds float64 `csv:"weight-lb"` } RegisterRowStruct(reflect.TypeOf(&Pet{})) henry := &Pet{} err := ParseRow(NewRow( []string{"ignored", "Henry", "32.15"}, NewHeader([]string{"id", "pet-name", "weight-lb"}), 1, "example.csv"), henry) if err != nil { fmt.Printf("error: %v", err) return } fmt.Printf("%q weighs %d pounds", henry.Name, int(henry.WeightPounds))
Output: "Henry" weighs 32 pounds
func SafeRegisterRowStruct ¶
func SafeRegisterRowStruct(t reflect.Type, opt ...RegisterOption) error
SafeRegisterRowStruct calls RegisterRowStruct but returns an error instead of panicking if there are any issues.
Types ¶
type CellContext ¶
type CellContext struct {
// contains filtered or unexported fields
}
CellContext is passed to the function parsing a single CSV cell.
func NewCellContext ¶
func NewCellContext(rctx *Row) *CellContext
NewCellContext returns a new CellContext to use when parsing within a given Row.
func (*CellContext) Row ¶
func (c *CellContext) Row() *Row
Row returns the row that is being parsed.
type ColumnNumber ¶
type ColumnNumber int
ColumnNumber is used instead of an int for column indexes.
const InvalidColumn ColumnNumber = -1
InvalidColumn returns an invalid column number.
func (ColumnNumber) IsValid ¶
func (n ColumnNumber) IsValid() bool
IsValid returns whether the column refers to a valid column in the CSV file or or not.
func (ColumnNumber) Offset ¶
func (n ColumnNumber) Offset() int
Offset returns the offset of the value within a row.
type FileParser ¶
type FileParser struct {
// contains filtered or unexported fields
}
FileParser is an object used to parse an entire CSV file.
func NewFileParser ¶
func NewFileParser(r RowReader, path string, recordPrototype interface{}) (*FileParser, error)
NewFileParser returns an object for parsing a set of records from a file.
The input RowReader will be used to read all rows. The path argument is only for error reporting purposes.
The type of the recordPrototype should have been registered with a call to RegisterRowStruct.
func (*FileParser) Read ¶
func (fp *FileParser) Read() (interface{}, error)
Read parses the next record in the CSV. The header is parsed automatically.
func (*FileParser) ReadAll ¶
func (fp *FileParser) ReadAll(callback func(interface{}) error) error
ReadAll calls Read() until the end of the file and calls cb for each value.
type Header ¶
type Header struct {
// contains filtered or unexported fields
}
Header contains the values of the first row of the CSV file.
func (*Header) ColumnIndex ¶
func (h *Header) ColumnIndex(col string) ColumnNumber
ColumnIndex returns the index of the column with the given name.
func (*Header) ColumnNames ¶
ColumnNames returns the names of the columns.
type RegisterOption ¶ added in v0.0.6
type RegisterOption struct { }
RegisterOption objects may be passed to RegisterRowStruct to configure how a type should be parsed as a CSV row.
type Row ¶
type Row struct {
// contains filtered or unexported fields
}
Row is passed to Unmarshal
func (*Row) Path ¶
Path returns the path of the CSV file or empty if this information is not available.
func (*Row) PositionString ¶
PositionString returns a human readable representation of the row position.
type RowNumber ¶
type RowNumber int
RowNumber is used instead of an int for representing the position of a row in a CSV file.
const InvalidRow RowNumber = -1
InvalidRow returns an invalid row number.
func (RowNumber) IsValid ¶
IsValid returns whether the row refers to a valid row in the CSV file or or not.