Browse Source

introduce NewReadCloser to allow byte and string buffers to offer io.ReadCloser

Signed-off-by: Alejandro Mery <amery@jpi.io>
Alejandro Mery 1 year ago
parent
commit
88966c1a7d
  1. 68
      readcloser.go

68
readcloser.go

@ -0,0 +1,68 @@
package core
import (
"bytes"
"io"
"io/fs"
"strings"
)
var (
_ io.Reader = (*ReadCloser)(nil)
_ io.Closer = (*ReadCloser)(nil)
)
// ReadCloser adds a Close() to Readers without one
type ReadCloser struct {
r io.Reader
}
// Read passes the Read() call to the underlying [io.Reader]
// and fail if it was Closed()
func (rc *ReadCloser) Read(b []byte) (int, error) {
switch {
case rc.r != nil:
return rc.r.Read(b)
default:
return 0, fs.ErrClosed
}
}
// Close attempts to Close the underlying [io.Reader], or
// remove it if it doesn't support Close() and fail
// if closed twice
func (rc *ReadCloser) Close() error {
switch p := rc.r.(type) {
case io.Closer:
return p.Close()
case nil:
return fs.ErrClosed
default:
rc.r = nil
return nil
}
}
// NewReadCloser wraps a [io.Reader] to satisfy
// [io.ReadCloser]
func NewReadCloser(r io.Reader) *ReadCloser {
if r == nil {
return nil
}
return &ReadCloser{
r: r,
}
}
// NewReadCloserBytes wraps a bytes slice to implement
// a [io.ReadCloser]
func NewReadCloserBytes(b []byte) *ReadCloser {
return NewReadCloser(bytes.NewReader(b))
}
// NewReadCloserString wraps a string to implement
// a [io.ReadCloser]
func NewReadCloserString(s string) *ReadCloser {
return NewReadCloser(strings.NewReader(s))
}
Loading…
Cancel
Save