asciigoat's core library https://asciigoat.org/core
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

64 lines
1.2 KiB

package core
import (
"bytes"
"io"
"io/fs"
"strings"
)
// 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 {
case rc.r != nil:
rc.r = nil
return nil
default:
return fs.ErrClosed
}
}
// NewReadCloser wraps a [io.Reader] to satisfy
// [io.ReadCloser] if needed
func NewReadCloser(r io.Reader) io.ReadCloser {
switch p := r.(type) {
case io.ReadCloser:
return p
case nil:
return nil
default:
return &ReadCloser{
r: r,
}
}
}
// NewReadCloserBytes wraps a bytes slice to implement
// a [io.ReadCloser]
func NewReadCloserBytes(b []byte) io.ReadCloser {
return NewReadCloser(bytes.NewReader(b))
}
// NewReadCloserString wraps a string to implement
// a [io.ReadCloser]
func NewReadCloserString(s string) io.ReadCloser {
return NewReadCloser(strings.NewReader(s))
}