Implement io.WriterTo with JSON

Viewed 99

I found this cool interface recently, io.WriterTo:

https://godocs.io/io#WriterTo

I would like to implement it for some JSON objects. I was able to make this:

package calendar

import (
   "bytes"
   "encoding/json"
   "io"
)

type date struct {
   Month int
   Day int
}

func (d date) WriteTo(w io.Writer) (int64, error) {
   buf := new(bytes.Buffer)
   err := json.NewEncoder(buf).Encode(d)
   if err != nil {
      return 0, err
   }
   return buf.WriteTo(w)
}

But I think it's not ideal, as it makes a copy of the object in memory, before sending to the Writer. Is it possible to write directly, but also know how many bytes were written?

1 Answers

To write directly, create an io.Writer wrapper that counts the bytes written:

type countingWriter struct {
    n int64
    w io.Writer
}

func (cw *countingWriter) Write(p []byte) (int, error) {
    n, err := cw.w.Write(p)
    cw.n += int64(n)
    return n, err
}

Change the WriteTo method to encode to a writer where the writer is the wrapper on the argument. Return the count of bytes and error when done.

func (d date) WriteTo(w io.Writer) (int64, error) {
    cw := &countingWriter{w: w}
    err := json.NewEncoder(cw).Encode(d)
    return cw.n, err
}

Run an example on the the Go PlayGround

Related