lotus/api/wrap.go

54 lines
1.4 KiB
Go
Raw Normal View History

2021-04-05 11:23:46 +00:00
package api
2021-04-05 17:56:53 +00:00
import (
"reflect"
)
2021-04-05 11:23:46 +00:00
// Wrap adapts partial api impl to another version
// proxyT is the proxy type used as input in wrapperT
// Usage: Wrap(new(v1api.FullNodeStruct), new(v0api.WrapperV1Full), eventsApi).(EventAPI)
func Wrap(proxyT, wrapperT, impl interface{}) interface{} {
proxy := reflect.New(reflect.TypeOf(proxyT).Elem())
2021-04-05 17:56:53 +00:00
proxyMethods := proxy.Elem().FieldByName("Internal")
2021-04-05 11:23:46 +00:00
ri := reflect.ValueOf(impl)
for i := 0; i < ri.NumMethod(); i++ {
mt := ri.Type().Method(i)
2021-04-05 19:34:03 +00:00
if proxyMethods.FieldByName(mt.Name).Kind() == reflect.Invalid {
2021-04-05 17:56:53 +00:00
continue
}
fn := ri.Method(i)
of := proxyMethods.FieldByName(mt.Name)
proxyMethods.FieldByName(mt.Name).Set(reflect.MakeFunc(of.Type(), func(args []reflect.Value) (results []reflect.Value) {
return fn.Call(args)
}))
2021-04-05 11:23:46 +00:00
}
2021-06-28 17:00:37 +00:00
for i := 0; i < proxy.Elem().NumField(); i++ {
if proxy.Elem().Type().Field(i).Name == "Internal" {
continue
}
subProxy := proxy.Elem().Field(i).FieldByName("Internal")
for i := 0; i < ri.NumMethod(); i++ {
mt := ri.Type().Method(i)
if subProxy.FieldByName(mt.Name).Kind() == reflect.Invalid {
continue
}
fn := ri.Method(i)
of := subProxy.FieldByName(mt.Name)
subProxy.FieldByName(mt.Name).Set(reflect.MakeFunc(of.Type(), func(args []reflect.Value) (results []reflect.Value) {
return fn.Call(args)
}))
}
}
2021-04-05 11:23:46 +00:00
wp := reflect.New(reflect.TypeOf(wrapperT).Elem())
2021-04-05 17:56:53 +00:00
wp.Elem().Field(0).Set(proxy)
2021-04-05 11:23:46 +00:00
return wp.Interface()
2021-04-05 11:47:10 +00:00
}