Exemple #1
0
/**
 * Given a type and any value, return a runtime value coerced to match the type.
 */
func coerceValue(typ typs.QLType, value interface{}) interface{} {
	if typ, ok := typ.(*typs.QLNonNull); ok {
		nullableType := typ.OfType
		return coerceValue(nullableType, value)
	}

	v := reflect.ValueOf(value)
	if value == nil || v.IsNil() {
		return nil
	}

	switch typ := typ.(type) {
	case *typs.QLList:
		itemType := typ.OfType
		if v.Kind() == reflect.Slice || v.Kind() == reflect.Array {
			result := make([]interface{}, v.Len())[:0]
			for i, n := 0, v.Len(); i < n; i++ {
				fieldValue := v.Field(i)
				result = append(result, coerceValue(itemType, fieldValue))
			}
			return result
		}
		return []interface{}{coerceValue(itemType, value)}

	case *typs.QLInputObject:
		fields := typ.GetFields()
		obj := make(map[string]interface{})
		for fieldName, field := range fields {
			runtimeField := v.FieldByName(fieldName)
			if !runtimeField.IsValid() {
				continue
			}

			fieldValue := coerceValue(field.Type, runtimeField.Interface())
			if fieldValue == nil {
				fieldValue = field.DefaultValue
			}
			if fieldValue != nil {
				obj[fieldName] = fieldValue
			}
		}
		return obj

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

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

	default:
		panic("Must be input type")
	}
}