{snapshot,backup}: Keep track of errors when writing report

This commit is contained in:
Tom Wiesing 2022-09-13 14:37:04 +02:00
parent 40a1aafbee
commit ac43221932
No known key found for this signature in database
3 changed files with 124 additions and 51 deletions

62
pkg/countwriter/writer.go Normal file
View file

@ -0,0 +1,62 @@
package countwriter
import (
"io"
)
// CountWriter wraps an io.Writer, see [NewCountWriter].
//
// It is intended to be used to count different writes to an underlying writer.
// Once an error occurs, no more writes are passed through, and the underlying error is returned instead.
// This means that in practice, calls to write can be continued and are ignored silently.
//
// The underlying sum of bytes written and error can be seen using [Sum].
type CountWriter struct {
w io.Writer
n int
err error
}
// NewCountWriter creates a new [CountWriter] that delegates to w.
func NewCountWriter(w io.Writer) *CountWriter {
return &CountWriter{w: w}
}
// write performs the write operation w on this writer.
func (cw *CountWriter) write(w func() (int, error)) (int, error) {
// if there was an error, return it and don't do a write
if cw.err != nil {
return 0, cw.err
}
// call the writer
n, err := w()
// update the underling state
cw.n += n
cw.err = err
// and return
return n, err
}
// Write implements [io.Writer]
func (cw *CountWriter) Write(p []byte) (int, error) {
return cw.write(func() (int, error) {
return cw.w.Write(p)
})
}
// WriteString implements [io.WriteString].
// See [Write].
func (cw *CountWriter) WriteString(s string) (int, error) {
return cw.write(func() (int, error) {
return io.WriteString(cw.w, s)
})
}
// Sum returns the state, that is the total number of bytes written and any error
func (cw *CountWriter) Sum() (int, error) {
return cw.n, cw.err
}