Beispiel #1
0
func IsValidGoValue(value interface{}, typ typs.QLInputType) bool {
	v := reflect.ValueOf(value)
	if typ, ok := typ.(*typs.QLNonNull); ok {
		if value == nil || v.IsNil() {
			return false
		}
		nullableType := typ.OfType.(typs.QLInputType)
		return IsValidGoValue(value, nullableType)
	}

	if value == nil || v.IsNil() {
		return true
	}

	v = reflect.Indirect(v)
	switch typ := typ.(type) {
	case *typs.QLList:
		itemType := typ.OfType.(typs.QLInputType)
		if v.Kind() == reflect.Slice || v.Kind() == reflect.Array {
			for i, n := 0, v.Len(); i < n; i++ {
				item := v.Index(i)
				if !IsValidGoValue(item, itemType) {
					return false
				}
			}
		}
		return IsValidGoValue(value, itemType)

	case *typs.QLInputObject:
		if v.Kind() != reflect.Struct {
			return false
		}
		t := v.Type()
		fieldsMap := typ.GetFields()
		for i, n := 0, t.NumField(); i < n; i++ {
			field := t.Field(i)
			fieldValue := v.Field(i)
			fieldType := fieldsMap[field.Name]
			if fieldType == nil || !IsValidGoValue(fieldValue, fieldType.Type) {
				return false
			}
		}
		return true

	case *typs.QLScalar:
		return !IsNil(typ.ParseValue(value))

	case *typs.QLEnum:
		return !IsNil(typ.ParseValue(value))

	default:
		panic("unreachable")
	}
}