I'm wrapping a http.ResponseWriter to track bandwidth use and peek at headers before they're sent. There's a helper function http.ServeContent that makes use of several extra optional methods on response writers, such as Flush, and via io.CopyN, ReaderFrom. For performance and transparency reasons it's desirable that my wrapper offer these functions when type assertions check for them. But their supposed existence depends on whether the wrapped response writer implements them. By using anonymous fields, it's possible to mix and optionally override the methods those fields types provide. However type assertions don't also pass through to the embedded fields. Here's an example:
http://play.golang.org/p/t9AZNb1MiG. In the example, Eminem is stored as a poser, but he's actually the Real Slim Shady. But attempts to type assert him so don't work.
What are my options here? If my wrapper purports to implement methods that its embedded types *may* implement, I risk changing the behaviour of callers, and having to implement work arounds when the embedded types don't actually support something.
For a concrete example:
type wrapper struct {
http.ResponseWriter
}
func (me wrapper) ReadFrom(src io.Reader) (int64, error) {
if rf, ok := me.ResponseWriter.(io.ReaderFrom); ok {
return rf.ReadFrom(src)
}
// ????
return io.Copy(me.ResponseWriter, src)
}