github.com/niko0xdev/gqlgen@v0.17.55-0.20240120102243-2ecff98c3e37/graphql/input.go (about)

     1  package graphql
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"reflect"
     7  )
     8  
     9  const unmarshalInputCtx key = "unmarshal_input_context"
    10  
    11  // BuildUnmarshalerMap returns a map of unmarshal functions of the ExecutableContext
    12  // to use with the WithUnmarshalerMap function.
    13  func BuildUnmarshalerMap(unmarshaler ...interface{}) map[reflect.Type]reflect.Value {
    14  	maps := make(map[reflect.Type]reflect.Value)
    15  	for _, v := range unmarshaler {
    16  		ft := reflect.TypeOf(v)
    17  		if ft.Kind() == reflect.Func {
    18  			maps[ft.Out(0)] = reflect.ValueOf(v)
    19  		}
    20  	}
    21  
    22  	return maps
    23  }
    24  
    25  // WithUnmarshalerMap returns a new context with a map from input types to their unmarshaler functions.
    26  func WithUnmarshalerMap(ctx context.Context, maps map[reflect.Type]reflect.Value) context.Context {
    27  	return context.WithValue(ctx, unmarshalInputCtx, maps)
    28  }
    29  
    30  // UnmarshalInputFromContext allows unmarshaling input object from a context.
    31  func UnmarshalInputFromContext(ctx context.Context, raw, v interface{}) error {
    32  	m, ok := ctx.Value(unmarshalInputCtx).(map[reflect.Type]reflect.Value)
    33  	if m == nil || !ok {
    34  		return errors.New("graphql: the input context is empty")
    35  	}
    36  
    37  	rv := reflect.ValueOf(v)
    38  	if rv.Kind() != reflect.Ptr || rv.IsNil() {
    39  		return errors.New("graphql: input must be a non-nil pointer")
    40  	}
    41  	if fn, ok := m[rv.Elem().Type()]; ok {
    42  		res := fn.Call([]reflect.Value{
    43  			reflect.ValueOf(ctx),
    44  			reflect.ValueOf(raw),
    45  		})
    46  		if err := res[1].Interface(); err != nil {
    47  			return err.(error)
    48  		}
    49  
    50  		rv.Elem().Set(res[0])
    51  		return nil
    52  	}
    53  
    54  	return errors.New("graphql: no unmarshal function found")
    55  }