Skip to content

Tool for creating proxies for interfaces and structs in Go.

License

Notifications You must be signed in to change notification settings

PanagiotisPtr/proxygen

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

26 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

proxygen

Proxygen allows you to generate proxies for Go interfaces. These are useful if you want to add middleware/handlers before a call is made to add observability for example. Even in big codebases this tool should be fairly fast (0-1sec per file) as it only parses the files top-down and doesn't look at nested dependencies unless it has to. The parsing is done using the golang.org/x/tools/go/packages package. You will also notice that this tool does not use the reflect package so it fast at runtime as well.

Installation

Install the proxygen tool

go install github.com/panagiotisptr/proxygen/cmd/proxygen@latest

Quickstart

Say that you have an interface that looks like this:

package example

import "context"

type ExampleContext interface {
	context.Context
	ValuesChannel() <-chan interface{}
}

You can run this command (in the root of your project) to generate a proxy for that interface:

proxygen \
    --interface github.com/panagiotisptr/demo/example.ExampleContext \
    --package example \
    --name ExampleProxy \
    --output demo/example/example_proxy.go

Which will generate this code in demo/example/example_proxy.go:

View generated code
// Code generated by proxygen. DO NOT EDIT.
package example

import (
	proxygenInterceptors "github.com/panagiotisptr/proxygen/interceptor"

	importcontextContext5 "time"
)

type ExampleContextProxy struct {
	Implementation ExampleContext
	Interceptors   proxygenInterceptors.InterceptorChain
}

var _ ExampleContext = (*ExampleContextProxy)(nil)

func (this *ExampleContextProxy) ValuesChannel() <-chan interface{} {
	rets := this.Interceptors.Apply(
		[]interface{}{},
		"ValuesChannel",
		func(args []interface{}) []interface{} {
			res0 := this.Implementation.ValuesChannel()

			return []interface{}{
				res0,
			}
		},
	)

	return rets[0].(<-chan interface{})
}

func (this *ExampleContextProxy) Deadline() (
	importcontextContext5.Time,
	bool,
) {
	rets := this.Interceptors.Apply(
		[]interface{}{},
		"Deadline",
		func(args []interface{}) []interface{} {
			res0,
				res1 := this.Implementation.Deadline()

			return []interface{}{
				res0,
				res1,
			}
		},
	)

	return rets[0].(importcontextContext5.Time),
		rets[1].(bool)
}

func (this *ExampleContextProxy) Done() <-chan struct{} {
	rets := this.Interceptors.Apply(
		[]interface{}{},
		"Done",
		func(args []interface{}) []interface{} {
			res0 := this.Implementation.Done()

			return []interface{}{
				res0,
			}
		},
	)

	return rets[0].(<-chan struct{})
}

func (this *ExampleContextProxy) Err() error {
	rets := this.Interceptors.Apply(
		[]interface{}{},
		"Err",
		func(args []interface{}) []interface{} {
			res0 := this.Implementation.Err()

			return []interface{}{
				res0,
			}
		},
	)

	return rets[0].(error)
}

func (this *ExampleContextProxy) Value(
	arg0 any,
) any {
	rets := this.Interceptors.Apply(
		[]interface{}{
			arg0,
		},
		"Value",
		func(args []interface{}) []interface{} {
			res0 := this.Implementation.Value(
				args[0].(any),
			)

			return []interface{}{
				res0,
			}
		},
	)

	return rets[0].(any)
}

If you then have an implementation of that interface you can create the proxy like so:

func NewExampleContext() ExampleContext {
    return &ExampleContext{
        Implementation: ExampleContextImplementation{},
        Interceptors: proxygen.InterceptorChain{
            func(method string, next Handler) Handler {
                return func(args []interface{}) []interface{} {
                    fmt.Println("called:", method)
                    return next(args)
                }
            },
        },
    }
}

Even if you don't have an interface for your struct you can easily generate it with ifacemaker.

About

Tool for creating proxies for interfaces and structs in Go.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages