vcsv

package module
v0.0.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 31, 2026 License: MIT Imports: 10 Imported by: 0

README

Go Reference

vcsv

This package is analogous to encoding/json but for csv.

See the godoc and examples for more details.

Documentation

Overview

Package vcsv converts CSV format text into structs and vice-versa. See the encoding/csv package for details on the CSV format, as this package uses encoding/csv internally.

Reading

Only conversion from CSV into structs is supported.

This package's conversion behavior closely mimics that of encoding/json. By default, exported struct fields are considered during reading by their name. e.g. a field with name Foo will be a candidate for receiving the parsed value of a column name foo, ignoring case.

Reading is supported for the following types

  • integers, parsed using strconv.ParseInt
  • unsigned integers, parsed using strconv.ParseUint
  • string
  • bool, parsed using strconv.ParseBool
  • floats, parsed using strconv.ParseFloat
  • any type T where *T implements CSVUnmarshaler
  • any type T where *T implements encoding.TextUnmarshaler

Struct fields can be be tagged with `csv:"name"` to cause the column "name" to be unmarshaled into that field. e.g. The CSV

first_name,last_name,date_of_birth
Alex,Bar,2007-12-30
Mike,Chess,2001-01-01

can be decoded into

type foo struct {
    First string `csv:"first_name"`
    Last  string `csv:"last_name"`
    DOB   string `csv:"date_of_birth"
}

Writing

Writer and the associated package-level functions encode structs into csv. By default, all exported fields of a struct are encoded using their field name. A `csv` tag can be added to a field to change the column name of that field.

e.g. instances of the struct

type foo struct {
    First string `csv:"first_name"`
    Last  string `csv:"last_name"`
    DOB   string `csv:"date_of_birth"
}

would be encoded as

first_name,last_name,date_of_birth
Alex,Bar,2007-12-30
Mike,Chess,2001-01-01

The special tag "-" will result in an exported field being ignored during reading and writing.

See the examples for more examples.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Read

func Read[T any](ioR io.Reader) ([]T, error)

Read decodes all the lines of the provided io.Reader into a slice of the desired type T.

Example
type s struct {
	First string `csv:"first_name"`
	Last  string `csv:"last_name"`
	Age   int
}

const csv = `first_name,last_name,age
Vlad,Yev,30
Maya,K,29`

decoded, err := Read[s](strings.NewReader(csv))
if err != nil {
	panic(err)
}

for _, it := range decoded {
	fmt.Printf("%+v\n", it)
}
Output:
{First:Vlad Last:Yev Age:30}
{First:Maya Last:K Age:29}

func ReadFile

func ReadFile[T any](path string) ([]T, error)

ReadFile reads all the CSV content in the file located at path.

func Write added in v0.0.3

func Write[T any](w io.Writer, s []T) error

Write writes the csv-encoded slice of structs into the provided writer.

Example
type s struct {
	First   string `csv:"first_name"`
	Last    string `csv:"last_name"`
	Ignored string `csv:"-"`
	Age     int
}

rows := []s{
	{
		First:   "vlad",
		Last:    "yev",
		Ignored: "foo",
		Age:     30,
	},
	{
		First:   "maya",
		Last:    "k",
		Ignored: "bar",
		Age:     29,
	},
}

var buf strings.Builder
if err := Write(&buf, rows); err != nil {
	panic(err)
}

fmt.Println(buf.String())
Output:
first_name,last_name,Age
vlad,yev,30
maya,k,29

func WriteFile added in v0.0.3

func WriteFile[T any](path string, s []T) error

WriteFile writes csv-encoded slice of structs into the file at path.

Types

type CSVMarshaler

type CSVMarshaler interface {
	MarshalCSV() (string, error)
}

CSVMarshaler is an interface that a type can implement to enable it to be csv-encoded in a custom way.

type CSVUnmarshaler

type CSVUnmarshaler interface {
	UnmarshalCSV(s string) error
}

CSVUnmarshaler can be implemented on a type to customize decoding behavior when decoding a CSV string into it.

type Reader

type Reader[T any] struct {
	// contains filtered or unexported fields
}

Reader is used to read CSV format directly into struct.

func NewReader

func NewReader[T any](r io.Reader) *Reader[T]

NewReader returns a new reader that reads from r. It uses the default settings described in encoding/csv.

panics if T is not a struct type.

func NewReaderFromCSV

func NewReaderFromCSV[T any](r *csv.Reader) *Reader[T]

NewReaderFromCSV returns a new reader that reads from r. Use this if you want csv.Reader behavior different from the defaults.

panics if T is not a struct type.

Example
type s struct {
	First string `csv:"first_name"`
	Last  string `csv:"last_name"`
	Age   int
}

const csvStr = `first_name;last_name;age
Vlad;Yev;30
Maya;K;29`

csvR := csv.NewReader(strings.NewReader(csvStr))
csvR.Comma = ';'

r := NewReaderFromCSV[s](csvR)

decoded, err := r.ReadAll()
if err != nil {
	panic(err)
}

for _, it := range decoded {
	fmt.Printf("%+v\n", it)
}
Output:
{First:Vlad Last:Yev Age:30}
{First:Maya Last:K Age:29}

func (*Reader[T]) Read

func (r *Reader[T]) Read() (T, error)

Read reads a single CSV line and decodes it into the desired type T.

Example
type s struct {
	First string `csv:"first_name"`
	Last  string `csv:"last_name"`
	Age   int
}

const csv = `first_name,last_name,age
Vlad,Yev,30
Maya,K,29`

r := NewReader[s](strings.NewReader(csv))

for {
	it, err := r.Read()
	if err != nil {
		if errors.Is(err, io.EOF) {
			break
		}
		panic(err)
	}

	fmt.Printf("%+v\n", it)
}
Output:
{First:Vlad Last:Yev Age:30}
{First:Maya Last:K Age:29}

func (*Reader[T]) ReadAll

func (r *Reader[T]) ReadAll() ([]T, error)

ReadAll reads all CSV lines and returns a slice of T corresponding to those lines.

Example
type s struct {
	First string `csv:"first_name"`
	Last  string `csv:"last_name"`
	Age   int
}

const csv = `first_name,last_name,age
Vlad,Yev,30
Maya,K,29`

r := NewReader[s](strings.NewReader(csv))

decoded, err := r.ReadAll()
if err != nil {
	panic(err)
}

for _, it := range decoded {
	fmt.Printf("%+v\n", it)
}
Output:
{First:Vlad Last:Yev Age:30}
{First:Maya Last:K Age:29}

func (*Reader[T]) SetColumnNames

func (r *Reader[T]) SetColumnNames(names []string)

SetColumnNames causes the reader to expect the provided column names in the provided order.

By default, Reader uses the first row of the CSV as the column names. This method should be called prior to Read-ing in order to override this default behavior.

panics if column names have already been set by a previous call or by a Read that took the 1st line of a csv as the column names.

Example
type s struct {
	First string `csv:"first_name"`
	Last  string `csv:"last_name"`
	Age   int
}

const csv = `30,Yev,Vlad
29,K,Maya`

r := NewReader[s](strings.NewReader(csv))
r.SetColumnNames([]string{"age", "last_name", "first_name"})

decoded, err := r.ReadAll()
if err != nil {
	panic(err)
}

for _, it := range decoded {
	fmt.Printf("%+v\n", it)
}
Output:
{First:Vlad Last:Yev Age:30}
{First:Maya Last:K Age:29}

type Writer

type Writer[T any] struct {
	// contains filtered or unexported fields
}

Writer writes items of type T into a CSV format.

func NewWriter

func NewWriter[T any](w io.Writer) *Writer[T]

NewWriter returns a Writer with a default configuration. The default configuration is described by encoding/csv.

func NewWriterFromCSV

func NewWriterFromCSV[T any](w *csv.Writer) *Writer[T]

NewWriterFromCSV returns a new writer using the provided *csv.Writer. This can be used to configure the csv writing behavior, such as the Comma character. See encoding/csv.Writer for more info.

Example
type s struct {
	First string `csv:"first_name"`
	Last  string `csv:"last_name"`
	Age   int
}

rows := []s{
	{
		First: "vlad",
		Last:  "yev",
		Age:   30,
	},
	{
		First: "maya",
		Last:  "k",
		Age:   29,
	},
}

var buf strings.Builder
csvW := csv.NewWriter(&buf)
csvW.Comma = ';'
w := NewWriterFromCSV[s](csvW)

if err := w.WriteAll(rows); err != nil {
	panic(err)
}
if err := w.Flush(); err != nil {
	panic(err)
}

fmt.Println(buf.String())
Output:
first_name;last_name;Age
vlad;yev;30
maya;k;29

func (*Writer[T]) Flush

func (w *Writer[T]) Flush() error

func (*Writer[T]) SetColumnNames added in v0.0.3

func (w *Writer[T]) SetColumnNames(names []string)

SetColumnNames uses the provided names as the csv column names. It causes the Writer to map fields of T to the values of names. names must be a subset of the exported fields of T. i.e. you can provide fewer names than exported fields to write only some of them.

panics if called more than once. panics if a name does not map to an exported field in T.

func (*Writer[T]) Write

func (w *Writer[T]) Write(t T) error

Write csv-encodes a single item of type T.

func (*Writer[T]) WriteAll

func (w *Writer[T]) WriteAll(ts []T) error

WriterAll writes all of the items in the provided slice.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL