github.com/sohaha/zlsgo@v1.7.13-0.20240501141223-10dd1a906f76/znet/inject.go (about)

     1  package znet
     2  
     3  import (
     4  	"errors"
     5  	"net/http"
     6  	"reflect"
     7  
     8  	"github.com/sohaha/zlsgo/zdi"
     9  	"github.com/sohaha/zlsgo/zjson"
    10  	"github.com/sohaha/zlsgo/zreflect"
    11  	"github.com/sohaha/zlsgo/ztype"
    12  )
    13  
    14  func handlerFuncs(h []Handler) (middleware []handlerFn, firstMiddleware []handlerFn) {
    15  	middleware = make([]handlerFn, 0, len(h))
    16  	firstMiddleware = make([]handlerFn, 0, len(h))
    17  	for i := range h {
    18  		fn := h[i]
    19  		if v, ok := fn.(firstHandler); ok {
    20  			firstMiddleware = append(firstMiddleware, Utils.ParseHandlerFunc(v[0]))
    21  		} else {
    22  			middleware = append(middleware, Utils.ParseHandlerFunc(fn))
    23  		}
    24  	}
    25  	return
    26  }
    27  
    28  func invokeHandler(c *Context, v []reflect.Value) (err error) {
    29  	for i := range v {
    30  		value := v[i]
    31  		v := value.Interface()
    32  		switch vv := v.(type) {
    33  		case int:
    34  			c.prevData.Code.Store(int32(vv))
    35  		case int32:
    36  			c.prevData.Code.Store(vv)
    37  		case uint:
    38  			c.prevData.Code.Store(int32(vv))
    39  		case string:
    40  			c.render = &renderString{Format: vv}
    41  		case error:
    42  			err = vv
    43  		case []byte:
    44  			c.render = &renderByte{Data: vv}
    45  		case ApiData:
    46  			c.render = &renderJSON{Data: vv}
    47  		default:
    48  			if vv != nil {
    49  				c.render = &renderJSON{Data: ApiData{Data: v}}
    50  			}
    51  		}
    52  	}
    53  	return
    54  }
    55  
    56  func (utils) ParseHandlerFunc(h Handler) (fn handlerFn) {
    57  	if h == nil {
    58  		return func(c *Context) error {
    59  			return errors.New("handler is nil")
    60  		}
    61  	}
    62  
    63  	switch v := h.(type) {
    64  	case HandlerFunc:
    65  		return func(c *Context) error {
    66  			v(c)
    67  			return nil
    68  		}
    69  	case func(*Context):
    70  		return func(c *Context) error {
    71  			v(c)
    72  			return nil
    73  		}
    74  	case func(*Context) (interface{}, error):
    75  		return func(c *Context) error {
    76  			res, err := v(c)
    77  
    78  			if c.stopHandle.Load() {
    79  				return nil
    80  			}
    81  
    82  			if err != nil {
    83  				return err
    84  			}
    85  
    86  			if res == nil {
    87  				res = struct{}{}
    88  			}
    89  			data := ApiData{
    90  				Data: res,
    91  			}
    92  			c.JSON(200, data)
    93  			return nil
    94  		}
    95  	case func(*Context) (ztype.Map, error):
    96  		return func(c *Context) error {
    97  			res, err := v(c)
    98  
    99  			if c.stopHandle.Load() {
   100  				return nil
   101  			}
   102  
   103  			if err != nil {
   104  				return err
   105  			}
   106  			data := ApiData{
   107  				Data: res,
   108  			}
   109  			c.JSON(200, data)
   110  			return nil
   111  		}
   112  	case handlerFn:
   113  		return v
   114  	case zdi.PreInvoker:
   115  		return func(c *Context) error {
   116  			v, err := c.injector.Invoke(v)
   117  
   118  			if c.stopHandle.Load() {
   119  				return nil
   120  			}
   121  
   122  			if err != nil {
   123  				return err
   124  			}
   125  
   126  			if len(v) == 0 {
   127  				return nil
   128  			}
   129  			return invokeHandler(c, v)
   130  		}
   131  	case func() (int, string):
   132  		return func(c *Context) error {
   133  			v, err := c.injector.Invoke(invokerCodeText(v))
   134  
   135  			if c.stopHandle.Load() {
   136  				return nil
   137  			}
   138  
   139  			c.String(int32(v[0].Int()), v[1].String())
   140  			return err
   141  		}
   142  	default:
   143  		val := zreflect.ValueOf(v)
   144  		if val.Kind() != reflect.Func {
   145  			b := ztype.ToBytes(v)
   146  			isJSON := zjson.ValidBytes(b)
   147  			return func(c *Context) error {
   148  				c.Byte(http.StatusOK, b)
   149  				if isJSON {
   150  					c.SetContentType(ContentTypeJSON)
   151  				}
   152  				return nil
   153  			}
   154  			// panic("znet Handler is not a function: " + val.Kind().String())
   155  		}
   156  
   157  		return func(c *Context) error {
   158  			v, err := c.injector.Invoke(v)
   159  
   160  			if c.stopHandle.Load() {
   161  				return nil
   162  			}
   163  
   164  			if err != nil {
   165  				return err
   166  			}
   167  
   168  			return invokeHandler(c, v)
   169  		}
   170  	}
   171  }