mcsv

package
v0.0.0-...-11eb462 Latest Latest
Warning

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

Go to latest
Published: Mar 5, 2023 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

mcsv is a wrapper around the built-in encoding/csv package, parsing RFC 4180 CSV files into map[string]string rows.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Reader

type Reader struct {
	// Reader.Reader is the [csv.Reader] actually used for parsing the CSV file.
	//
	// Almost all options of the [csv.Reader] are available and can be set
	// before the first call to Read / ReadAll.
	//
	// The two unavailable options are `ReuseRecord` and `FieldsPerRecord`,
	// those are controlled internally by the mcsv.Reader, and their values
	// must not be changed.
	*csv.Reader

	// Header is a slice of column names to be used as keys in returned records.
	//
	// Set by the first call to Read or NewReaderWithHeader, must not be modified.
	Header []string

	// ReuseRecord shadows the csv.Reader.ReuseRecord setting.
	//
	// If ReuseRecord is set to true, the same map will be returned by all calls to Read().
	//
	// Ignored by the ReadAll() function.
	//
	// The csv.Reader.ReuseRecord setting is controlled by mcsv.Reader and must not be changed.
	ReuseRecord bool

	// PreserveBOM ensures an initial byte-order-mark in the first ever read from the file
	// is not removed. The default behavior removes the BOM.
	PreserveBOM bool
	// contains filtered or unexported fields
}

Reader reads records from a CSV io.Reader.

Example
package main

import (
	"errors"
	"fmt"
	"io"
	"log"
	"strings"

	"github.com/MKuranowski/go-extra-lib/encoding/mcsv"
)

func main() {
	in := `number,value
pi,3.1416
sqrt2,1.4142
phi,1.618
e,2.7183
`

	r := mcsv.NewReader(strings.NewReader(in))

	for {
		record, err := r.Read()
		if errors.Is(err, io.EOF) {
			break
		} else if err != nil {
			log.Fatal(err)
		}

		fmt.Println("Number", record["number"], "has value", record["value"])
	}

}
Output:

Number pi has value 3.1416
Number sqrt2 has value 1.4142
Number phi has value 1.618
Number e has value 2.7183
Example (Missing_header)
package main

import (
	"errors"
	"fmt"
	"io"
	"log"
	"strings"

	"github.com/MKuranowski/go-extra-lib/encoding/mcsv"
)

func main() {
	in := `pi,3.1416
sqrt2,1.4142
phi,1.618
e,2.7183
`

	r := mcsv.NewReaderWithHeader(strings.NewReader(in), []string{"number", "value"})

	for {
		record, err := r.Read()
		if errors.Is(err, io.EOF) {
			break
		} else if err != nil {
			log.Fatal(err)
		}

		fmt.Println("Number", record["number"], "has value", record["value"])
	}

}
Output:

Number pi has value 3.1416
Number sqrt2 has value 1.4142
Number phi has value 1.618
Number e has value 2.7183

func NewReader

func NewReader(r io.Reader) *Reader

NewReader returns a Reader pulling CSV records from r.

The first row is assumed to be the header row.

func NewReaderWithHeader

func NewReaderWithHeader(r io.Reader, header []string) *Reader

NewReaderWithHeader returns a Reader pulling CSV records from r.

Assumes that r does not contain a header row; instead header is used as the column names. All rows in the CSV file must have len(header) fields.

func (*Reader) Read

func (r *Reader) Read() (record map[string]string, err error)

Read reads a record from the CSV file and returns it. Always returns either a non-nil record or a non-nil err, but never both. The exception from csv.Reader.Read does not apply. If there are no more records to read, returns (nil, io.EOF).

If ReuseRecord is set, this function may return the same map as a previous call to Read(), just with the values changed.

func (*Reader) ReadAll

func (r *Reader) ReadAll() (records []map[string]string, err error)

ReadAll repeatedly calls Read to read all remaining records from a file. If an error occurs, returns all records read up to the error and the error itself. Successful ReadAll call returns (records, nil), as io.EOF is not deemed an error in this context.

ReuseRecord setting is automatically set to false.

type Writer

type Writer struct {
	// Writer.Writer is the [csv.Writer] actually used for encoding and writing the CSV data.
	//
	// All options of the [csv.Writer] are available and can be set
	// before the first call to Read / ReadAll.
	*csv.Writer

	// Header is a slice of column names to be used as keys in returned records.
	//
	// Set by NewWriter, must not be modified after construction.
	Header []string
	// contains filtered or unexported fields
}

Writer writes CSV records into a io.Writer.

Writes to the underlying file are buffered and client must call Flush() to ensure data was actually written to the io.Writer. Any encountered errors may be checked with the Error() method.

Example
package main

import (
	"log"
	"os"

	"github.com/MKuranowski/go-extra-lib/encoding/mcsv"
)

func main() {
	data := []map[string]string{
		{"City": "Berlin", "Country": "Germany", "Population": "3 677 472"},
		{"City": "Madrid", "Country": "Spain", "Population": "3 223 334"},
		{"City": "Rome", "Country": "Italy"},
		{"City": "Bucharest", "Country": "Romania", "Area": "240 km²"},
		{"City": "Paris", "Country": "France", "Population": "2 165 423", "Area": "105 km²"},
	}

	w := mcsv.NewWriter(os.Stdout, []string{"City", "Country", "Population"})

	// Write the header row
	err := w.WriteHeader()
	if err != nil {
		log.Fatalln(err)
	}

	// Write every record
	for _, record := range data {
		err = w.Write(record)
		if err != nil {
			log.Fatalln(err)
		}
	}

	// Flush the output
	w.Flush()
	err = w.Error()
	if err != nil {
		log.Fatalln(err)
	}

}
Output:

City,Country,Population
Berlin,Germany,3 677 472
Madrid,Spain,3 223 334
Rome,Italy,
Bucharest,Romania,
Paris,France,2 165 423

func NewWriter

func NewWriter(w io.Writer, header []string) *Writer

NewWriter returns a *Writer for encoding records as CSV and writing them to an underlying io.Writer.

The header row is not written to the file by default - use the WriteHeader().

func (*Writer) Write

func (w *Writer) Write(record map[string]string) error

Write writes a record to the CSV file.

Any missing fields are replaced with an empty string, and extra fields are ignored.

All writes to the underlying io.Writer are buffered and some data may not be actually written unless Flush() is called.

func (*Writer) WriteAll

func (w *Writer) WriteAll(records []map[string]string) error

WriteAll calls Write for every provided record, and then calls Flush().

func (*Writer) WriteHeader

func (w *Writer) WriteHeader() error

WriteHeader writes the header row.

All writes to the underlying io.Writer are buffered and some data may not be actually written unless Flush() is called.

Jump to

Keyboard shortcuts

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