A tool to assist in creating wrappers for Go interfaces.
Consider creating a wrapper for http.ResponseWriter
. The simplest approach is to use embedding as shown below:
type MyResponseWriter struct {
http.ResponseWriter
}
func WrapResponseWriter(rw http.ResponseWriter) http.ResponseWriter {
return &MyResponseWriter{rw}
}
However, with this method, the result of type assertion changes after wrapping.
// ResponseWriter implemented with hijacker
var rw http.ResponseWriter
// Before wrap: ok => true
_, ok = rw.(http.Hijacker)
// After wrap: ok => false
_, ok = WrapResponseWriter(rw).(http.Hijacker)
Such type assertions, often performed in standard libraries to maintain backward compatibility, can lead to unexpected behavioral changes.
By using the function (ResponseWriterWrapper
) generated with iwrapper
, this problem can be addressed as shown below:
// 1. Implement http.Hijacker in MyResponseWriter
func (w *MyResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
return w.ResponseWriter.(http.Hijacker).Hijack()
}
// 2. Use ResponseWriterWrapper for wrapping
func WrapResponseWriterWithIWrapper(rw http.ResponseWriter) http.ResponseWriter {
return ResponseWriterWrapper(rw, func(rw http.ResponseWriter) ResponseWriter {
return &MyResponseWriter{rw}
})
}
// After wrapping using iwrapper: ok => true
_, ok = WrapResponseWriterWithIWrapper(rw).(http.Hijacker)
Consider wrapping http.ResponseWriter
so that the results of type assertions for http.Hijacker
, http.CloseNotifier
, and http.Flusher
remain unchanged:
- Create the following Go file as the configuration for iwrapper:
package testdata //go:generate go run github.com/mazrean/iwrapper -src=$GOFILE -dst=iwrapper_$GOFILE import ( "net/http" ) //iwrapper:target type ResponseWriter interface { //iwrapper:require http.ResponseWriter http.Hijacker http.CloseNotifier http.Flusher }
- You can customize the generated function name with
iwrapper:target func:"ResponseWriterWrapFunc"
.
- You can customize the generated function name with
- Execute
go generate
.- This produces the wrapping function (
ResponseWriterWrapper
) iniwrapper_<configuration filename>.go
.
- This produces the wrapping function (
Detailed generated code and its usage examples are available in /example/
.
MIT