func NewCSVDecoder(r io.Reader) Decoder {
	dec := csv.NewReader(r)
	dec.FieldsPerRecord = 12
	dec.TrimLeadingSpace = true
	return func(r *Result) error {
		rec, err := dec.Read()
		if err != nil {
			return err
		}
		ts, err := strconv.ParseInt(rec[0], 10, 64)
		if err != nil {
			return err
		}
		r.Timestamp = time.Unix(0, ts)
		code, err := strconv.ParseUint(rec[1], 10, 16)
		if err != nil {
			return err
		}
		r.Code = uint16(code)
		latency, err := strconv.ParseInt(rec[2], 10, 64)
		if err != nil {
			return err
		}
		r.Latency = time.Duration(latency)
		if r.BytesOut, err = strconv.ParseUint(rec[3], 10, 64); err != nil {
			return err
		}
		if r.BytesIn, err = strconv.ParseUint(rec[4], 10, 64); err != nil {
			return err
		}
		r.Error = rec[5]
		if r.Body, err = base64.StdEncoding.DecodeString(rec[6]); err != nil {
			return err
		}
		r.Attack = rec[7]
		if r.Seq, err = strconv.ParseUint(rec[8], 10, 64); err != nil {
			return err
		}
		r.Method = rec[9]
		r.URL = rec[10]
		if rec[11] != "" {
			pr := textproto.NewReader(bufio.NewReader(
				base64.NewDecoder(base64.StdEncoding, strings.NewReader(rec[11]))))
			hdr, err := pr.ReadMIMEHeader()
			if err != nil {
				return err
			}
			r.Headers = http.Header(hdr)
		}
		return err
	}
}
NewCSVDecoder returns a Decoder that decodes CSV encoded Results.
package vegeta
import (
	"bufio"
	"bytes"
	"encoding/base64"
	"encoding/csv"
	"encoding/gob"
	"io"
	"net/http"
	"net/textproto"
	"sort"
	"strconv"
	"strings"
	"time"
	"github.com/mailru/easyjson/jlexer"
	"github.com/mailru/easyjson/jwriter"
)
func init() {
	gob.Register(&Result{})
}
type Result struct {
	Attack    string        `json:"attack"`
	Seq       uint64        `json:"seq"`
	Code      uint16        `json:"code"`
	Timestamp time.Time     `json:"timestamp"`
	Latency   time.Duration `json:"latency"`
	BytesOut  uint64        `json:"bytes_out"`
	BytesIn   uint64        `json:"bytes_in"`
	Error     string        `json:"error"`
	Body      []byte        `json:"body"`
	Method    string        `json:"method"`
	URL       string        `json:"url"`
	Headers   http.Header   `json:"headers"`
}
func (r *Result) End() time.Time { return r.Timestamp.Add(r.Latency) }
func (r Result) Equal(other Result) bool {
	return r.Attack == other.Attack &&
		r.Seq == other.Seq &&
		r.Code == other.Code &&
		r.Timestamp.Equal(other.Timestamp) &&
		r.Latency == other.Latency &&
		r.BytesIn == other.BytesIn &&
		r.BytesOut == other.BytesOut &&
		r.Error == other.Error &&
		bytes.Equal(r.Body, other.Body) &&
		r.Method == other.Method &&
		r.URL == other.URL &&
		headerEqual(r.Headers, other.Headers)
}
func headerEqual(h1, h2 http.Header) bool {
	if len(h1) != len(h2) {
		return false
	}
	if h1 == nil || h2 == nil {
		return h1 == nil && h2 == nil
	}
	for key, values1 := range h1 {
		values2 := h2[key]
		if len(values1) != len(values2) {
			return false
		}
		for i := range values1 {
			if values1[i] != values2[i] {
				return false
			}
		}
	}
	return true
}
type Results []Result
func (rs *Results) Add(r *Result) { *rs = append(*rs, *r) }
func (rs *Results) Close() { sort.Sort(rs) }
func (rs Results) Len() int           { return len(rs) }
func (rs Results) Less(i, j int) bool { return rs[i].Timestamp.Before(rs[j].Timestamp) }
func (rs Results) Swap(i, j int)      { rs[i], rs[j] = rs[j], rs[i] }
type Decoder func(*Result) error
type DecoderFactory func(io.Reader) Decoder
func DecoderFor(r io.Reader) Decoder {
	var buf bytes.Buffer
	for _, dec := range []DecoderFactory{
		NewDecoder,
		NewJSONDecoder,
		NewCSVDecoder,
	} {
		rd := io.MultiReader(bytes.NewReader(buf.Bytes()), io.TeeReader(r, &buf))
		if err := dec(rd).Decode(&Result{}); err == nil {
			return dec(io.MultiReader(&buf, r))
		}
	}
	return nil
}
func NewRoundRobinDecoder(dec ...Decoder) Decoder {
	if len(dec) == 1 {
		return dec[0]
	}
	var seq uint64
	return func(r *Result) (err error) {
		for range dec {
			robin := seq % uint64(len(dec))
			seq++
			if err = dec[robin].Decode(r); err != nil {
				continue
			}
			return nil
		}
		return err
	}
}
func NewDecoder(rd io.Reader) Decoder {
	dec := gob.NewDecoder(rd)
	return func(r *Result) error { return dec.Decode(r) }
}
func (dec Decoder) Decode(r *Result) error { return dec(r) }
type Encoder func(*Result) error
func NewEncoder(r io.Writer) Encoder {
	enc := gob.NewEncoder(r)
	return func(r *Result) error { return enc.Encode(r) }
}
func (enc Encoder) Encode(r *Result) error { return enc(r) }
func NewCSVEncoder(w io.Writer) Encoder {
	enc := csv.NewWriter(w)
	return func(r *Result) error {
		err := enc.Write([]string{
			strconv.FormatInt(r.Timestamp.UnixNano(), 10),
			strconv.FormatUint(uint64(r.Code), 10),
			strconv.FormatInt(r.Latency.Nanoseconds(), 10),
			strconv.FormatUint(r.BytesOut, 10),
			strconv.FormatUint(r.BytesIn, 10),
			r.Error,
			base64.StdEncoding.EncodeToString(r.Body),
			r.Attack,
			strconv.FormatUint(r.Seq, 10),
			r.Method,
			r.URL,
			base64.StdEncoding.EncodeToString(headerBytes(r.Headers)),
		})
		if err != nil {
			return err
		}
		enc.Flush()
		return enc.Error()
	}
}
func headerBytes(h http.Header) []byte {
	if h == nil {
		return nil
	}
	var hdr bytes.Buffer
	_ = h.Write(&hdr)
	return append(hdr.Bytes(), '\r', '\n')
}