Commit 112f28de authored by Daniel Martí's avatar Daniel Martí Committed by Brad Fitzpatrick

io: export StringWriter

And start using it elsewhere in the standard library, removing the
copies in the process.

While at it, rewrite the io.WriteString godoc to be more clear, since it
can now make reference to the defined interface.

Fixes #27946.

Change-Id: Id5ba223c09c19e5fb49815bd3b1bd3254fc786f3
Reviewed-on: https://go-review.googlesource.com/c/139457
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
Reviewed-by: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent c91ce3cc
......@@ -131,15 +131,10 @@ func (byteFormatter) Format(f State, _ rune) {
var byteFormatterSlice = []byteFormatter{'h', 'e', 'l', 'l', 'o'}
// Copy of io.stringWriter interface used by writeStringFormatter for type assertion.
type stringWriter interface {
WriteString(s string) (n int, err error)
}
type writeStringFormatter string
func (sf writeStringFormatter) Format(f State, c rune) {
if sw, ok := f.(stringWriter); ok {
if sw, ok := f.(io.StringWriter); ok {
sw.WriteString("***" + string(sf) + "***")
}
}
......
......@@ -278,16 +278,16 @@ type RuneScanner interface {
UnreadRune() error
}
// stringWriter is the interface that wraps the WriteString method.
type stringWriter interface {
// StringWriter is the interface that wraps the WriteString method.
type StringWriter interface {
WriteString(s string) (n int, err error)
}
// WriteString writes the contents of the string s to w, which accepts a slice of bytes.
// If w implements a WriteString method, it is invoked directly.
// If w implements StringWriter, its WriteString method is invoked directly.
// Otherwise, w.Write is called exactly once.
func WriteString(w Writer, s string) (n int, err error) {
if sw, ok := w.(stringWriter); ok {
if sw, ok := w.(StringWriter); ok {
return sw.WriteString(s)
}
return w.Write([]byte(s))
......
......@@ -69,12 +69,12 @@ func (t *multiWriter) Write(p []byte) (n int, err error) {
return len(p), nil
}
var _ stringWriter = (*multiWriter)(nil)
var _ StringWriter = (*multiWriter)(nil)
func (t *multiWriter) WriteString(s string) (n int, err error) {
var p []byte // lazily initialized if/when needed
for _, w := range t.writers {
if sw, ok := w.(stringWriter); ok {
if sw, ok := w.(StringWriter); ok {
n, err = sw.WriteString(s)
} else {
if p == nil {
......
......@@ -99,10 +99,6 @@ func ParseTime(text string) (t time.Time, err error) {
var headerNewlineToSpace = strings.NewReplacer("\n", " ", "\r", " ")
type writeStringer interface {
WriteString(string) (int, error)
}
// stringWriter implements WriteString on a Writer.
type stringWriter struct {
w io.Writer
......@@ -158,7 +154,7 @@ func (h Header) WriteSubset(w io.Writer, exclude map[string]bool) error {
}
func (h Header) writeSubset(w io.Writer, exclude map[string]bool, trace *httptrace.ClientTrace) error {
ws, ok := w.(writeStringer)
ws, ok := w.(io.StringWriter)
if !ok {
ws = stringWriter{w}
}
......
......@@ -4028,21 +4028,18 @@ func TestRequestBodyCloseDoesntBlock(t *testing.T) {
}
}
// test that ResponseWriter implements io.stringWriter.
// test that ResponseWriter implements io.StringWriter.
func TestResponseWriterWriteString(t *testing.T) {
okc := make(chan bool, 1)
ht := newHandlerTest(HandlerFunc(func(w ResponseWriter, r *Request) {
type stringWriter interface {
WriteString(s string) (n int, err error)
}
_, ok := w.(stringWriter)
_, ok := w.(io.StringWriter)
okc <- ok
}))
ht.rawResponse("GET / HTTP/1.0")
select {
case ok := <-okc:
if !ok {
t.Error("ResponseWriter did not implement io.stringWriter")
t.Error("ResponseWriter did not implement io.StringWriter")
}
default:
t.Error("handler was never called")
......
......@@ -308,10 +308,6 @@ func (w *appendSliceWriter) WriteString(s string) (int, error) {
return len(s), nil
}
type stringWriterIface interface {
WriteString(string) (int, error)
}
type stringWriter struct {
w io.Writer
}
......@@ -320,8 +316,8 @@ func (w stringWriter) WriteString(s string) (int, error) {
return w.w.Write([]byte(s))
}
func getStringWriter(w io.Writer) stringWriterIface {
sw, ok := w.(stringWriterIface)
func getStringWriter(w io.Writer) io.StringWriter {
sw, ok := w.(io.StringWriter)
if !ok {
sw = stringWriter{w}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment