github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/ginx/anyfn/anyfn.go (about) 1 package anyfn 2 3 import ( 4 "log" 5 "reflect" 6 7 "github.com/bingoohuang/gg/pkg/ginx/adapt" 8 "github.com/gin-gonic/gin" 9 "github.com/sirupsen/logrus" 10 ) 11 12 // DirectDealer is the dealer for a specified type. 13 type DirectDealer interface { 14 Deal(*gin.Context) 15 } 16 17 // HTTPStatus defines the type of HTTP state. 18 type HTTPStatus int 19 20 func (h HTTPStatus) Deal(c *gin.Context) { 21 c.Status(int(h)) 22 } 23 24 type Adapter struct { 25 InSupports []InSupport 26 OutSupports []OutSupport 27 } 28 29 func (a *Adapter) Default(relativePath string) adapt.Handler { return nil } 30 31 func (a *Adapter) Adapt(relativePath string, argV interface{}) adapt.Handler { 32 anyF, ok := argV.(*anyF) 33 if !ok { 34 return nil 35 } 36 37 fv := reflect.ValueOf(anyF.F) 38 39 return adapt.HandlerFunc(func(c *gin.Context) { 40 if err := a.internalAdapter(c, fv, anyF); err != nil { 41 logrus.Warnf("adapt error %v", err) 42 } 43 }) 44 } 45 46 func NewAdapter() *Adapter { 47 adapter := &Adapter{ 48 InSupports: []InSupport{ 49 InSupportFn(GinContextSupport), 50 InSupportFn(HTTPRequestSupport), 51 InSupportFn(HTTPResponseWriterSupport), 52 InSupportFn(ContextKeyValuesSupport), 53 InSupportFn(SinglePrimitiveValueSupport), // try single param 54 InSupportFn(BindSupport), // try bind 55 }, 56 OutSupports: []OutSupport{ 57 OutSupportFn(ErrorSupport), 58 OutSupportFn(DirectDealerSupport), 59 OutSupportFn(DefaultSupport), 60 }, 61 } 62 63 return adapter 64 } 65 66 type Before interface { 67 // Do will be called Before the adaptee invoking. 68 Do(args []interface{}) error 69 } 70 71 type BeforeFn func(args []interface{}) error 72 73 func (b BeforeFn) Do(args []interface{}) error { return b(args) } 74 75 type After interface { 76 // Do will be called Before the adaptee invoking. 77 Do(args []interface{}, results []interface{}) error 78 } 79 80 type AfterFn func(args []interface{}, results []interface{}) error 81 82 func (b AfterFn) Do(args []interface{}, results []interface{}) error { return b(args, results) } 83 84 type anyF struct { 85 P *Adapter 86 F interface{} 87 Option *Option 88 } 89 90 func (a *anyF) Parent() adapt.Adapter { return a.P } 91 92 type Option struct { 93 Before Before 94 After After 95 Attrs map[string]interface{} 96 } 97 98 type OptionFn func(*Option) 99 100 func (a *Adapter) Before(before Before) OptionFn { 101 return func(f *Option) { 102 f.Before = before 103 } 104 } 105 106 func (a *Adapter) After(after After) OptionFn { 107 return func(f *Option) { 108 f.After = after 109 } 110 } 111 112 func (a *Adapter) AttrMap(attrs map[string]interface{}) OptionFn { 113 return func(f *Option) { 114 for k, v := range attrs { 115 f.Attrs[k] = v 116 } 117 } 118 } 119 120 func (a *Adapter) Attr(k string, v interface{}) OptionFn { 121 return func(f *Option) { 122 f.Attrs[k] = v 123 } 124 } 125 126 func (a *Adapter) F(v interface{}, fns ...OptionFn) adapt.Parent { 127 option := &Option{ 128 Attrs: make(map[string]interface{}), 129 } 130 131 for _, fn := range fns { 132 fn(option) 133 } 134 135 return &anyF{F: v, Option: option} 136 } 137 138 func (a *Adapter) internalAdapter(c *gin.Context, fv reflect.Value, anyF *anyF) error { 139 argVs, err := a.createArgs(c, fv) 140 if err != nil { 141 return err 142 } 143 144 if err := a.before(argVs, anyF.Option.Before); err != nil { 145 return err 146 } 147 148 r := fv.Call(argVs) 149 150 if err := a.after(argVs, r, anyF.Option.After); err != nil { 151 return err 152 } 153 154 return a.processOut(c, fv, r) 155 } 156 157 func (a *Adapter) before(v []reflect.Value, f Before) error { 158 if f == nil { 159 return nil 160 } 161 162 return f.Do(Values(v).Interface()) 163 } 164 165 func (a *Adapter) after(v, results []reflect.Value, f After) error { 166 if f == nil { 167 return nil 168 } 169 170 return f.Do(Values(v).Interface(), Values(results).Interface()) 171 } 172 173 type Values []reflect.Value 174 175 func (v Values) Interface() []interface{} { 176 args := make([]interface{}, len(v)) 177 for i, a := range v { 178 args[i] = a.Interface() 179 } 180 181 return args 182 } 183 184 func (a *Adapter) processOut(c *gin.Context, fv reflect.Value, r []reflect.Value) error { 185 numOut := fv.Type().NumOut() 186 if numOut == 0 { 187 return nil 188 } 189 190 vs := make([]interface{}, 0, numOut) 191 for i := 0; i < numOut; i++ { 192 vs = append(vs, r[i].Interface()) 193 } 194 195 lastErrNil := false 196 if numOut > 0 { 197 if e, ok := vs[numOut-1].(error); ok { 198 if e != nil { 199 _, err := a.processOutV(c, e, vs) 200 return err 201 } else { 202 lastErrNil = true 203 } 204 } 205 } 206 207 if lastErrNil { 208 vs = vs[:numOut-1] 209 } 210 211 for _, v := range vs { 212 if processed, err := a.processOutV(c, v, vs); err != nil { 213 return err 214 } else if processed { 215 return nil 216 } 217 } 218 219 return nil 220 } 221 222 func (a *Adapter) processOutV(c *gin.Context, v interface{}, vs []interface{}) (bool, error) { 223 for _, support := range a.OutSupports { 224 if ok, err := support.OutSupport(v, vs, c); err != nil { 225 return false, err 226 } else if ok { 227 return true, nil 228 } 229 } 230 231 return false, nil 232 } 233 234 func (a *Adapter) createArgs(c *gin.Context, fv reflect.Value) (v []reflect.Value, err error) { 235 ft := fv.Type() 236 argIns := parseArgIns(ft) 237 v = make([]reflect.Value, ft.NumIn()) 238 239 for i, arg := range argIns { 240 if v[i], err = a.createArgValue(c, arg, argIns); err != nil { 241 return nil, err 242 } 243 } 244 245 return v, err 246 } 247 248 func (a *Adapter) createArgValue(c *gin.Context, arg ArgIn, argsIn []ArgIn) (reflect.Value, error) { 249 for _, support := range a.InSupports { 250 v, err := support.InSupport(arg, argsIn, c) 251 if err == nil && v.IsValid() { 252 return v, nil 253 } else if err != nil { 254 log.Printf("error parse argument %v: %v", arg, err) 255 } 256 257 } 258 259 return reflect.Zero(arg.Type), nil 260 }