public static IValue AstFromValue(this object value, ISchema schema, IGraphType type)
        {
            if (type is NonNullGraphType)
            {
                var nonnull = (NonNullGraphType)type;
                return(AstFromValue(value, schema, nonnull.ResolvedType));
            }

            if (value == null || type == null)
            {
                return(new NullValue());
            }

            // Convert IEnumerable to GraphQL list. If the GraphQLType is a list, but
            // the value is not an IEnumerable, convert the value using the list's item type.
            if (type is ListGraphType)
            {
                var listType = (ListGraphType)type;
                var itemType = listType.ResolvedType;

                if (!(value is string) && value is IEnumerable)
                {
                    var list   = (IEnumerable)value;
                    var values = list.Map(item => AstFromValue(item, schema, itemType));
                    return(new ListValue(values));
                }

                return(AstFromValue(value, schema, itemType));
            }

            // Populate the fields of the input object by creating ASTs from each value
            // in the dictionary according to the fields in the input type.
            if (type is InputObjectGraphType)
            {
                if (!(value is Dictionary <string, object>))
                {
                    return(null);
                }

                var input = (InputObjectGraphType)type;
                var dict  = (Dictionary <string, object>)value;

                var fields = dict
                             .Select(pair =>
                {
                    var field     = input.Fields.FirstOrDefault(x => x.Name == pair.Key);
                    var fieldType = field?.ResolvedType;
                    return(new ObjectField(pair.Key, AstFromValue(pair.Value, schema, fieldType)));
                })
                             .ToList();

                return(new ObjectValue(fields));
            }


            Invariant.Check(
                type.IsInputType(),
                $"Must provide Input Type, cannot use: {type}");


            var inputType = type as ScalarGraphType;

            // Since value is an internally represented value, it must be serialized
            // to an externally represented value before converting into an AST.
            var serialized = inputType.Serialize(value);

            if (serialized == null)
            {
                return(null);
            }

            if (serialized is bool)
            {
                return(new BooleanValue((bool)serialized));
            }

            if (serialized is int)
            {
                return(new IntValue((int)serialized));
            }

            if (serialized is long)
            {
                return(new LongValue((long)serialized));
            }

            if (serialized is decimal)
            {
                return(new DecimalValue((decimal)serialized));
            }

            if (serialized is double)
            {
                return(new FloatValue((double)serialized));
            }

            if (serialized is DateTime)
            {
                return(new DateTimeValue((DateTime)serialized));
            }

            if (serialized is string)
            {
                if (type is EnumerationGraphType)
                {
                    return(new EnumValue(serialized.ToString()));
                }

                return(new StringValue(serialized.ToString()));
            }

            throw new ExecutionError($"Cannot convert value to AST: {serialized}");
        }
Пример #2
0
        public static IValue AstFromValue(this object value, ISchema schema, IGraphType type)
        {
            if (type is NonNullGraphType nonnull)
            {
                return(AstFromValue(value, schema, nonnull.ResolvedType));
            }

            if (value == null || type == null)
            {
                return(new NullValue());
            }

            // Convert IEnumerable to GraphQL list. If the GraphQLType is a list, but
            // the value is not an IEnumerable, convert the value using the list's item type.
            if (type is ListGraphType listType)
            {
                var itemType = listType.ResolvedType;

                if (!(value is string) && value is IEnumerable list)
                {
                    var values = list
                                 .Cast <object>()
                                 .Select(item => AstFromValue(item, schema, itemType))
                                 .ToList();

                    return(new ListValue(values));
                }

                return(AstFromValue(value, schema, itemType));
            }

            // Populate the fields of the input object by creating ASTs from each value
            // in the dictionary according to the fields in the input type.
            if (type is IInputObjectGraphType input)
            {
                if (!(value is Dictionary <string, object> dict))
                {
                    return(null);
                }

                var fields = dict
                             .Select(pair =>
                {
                    var fieldType = input.GetField(pair.Key)?.ResolvedType;
                    return(new ObjectField(pair.Key, AstFromValue(pair.Value, schema, fieldType)));
                })
                             .ToList();

                return(new ObjectValue(fields));
            }


            Invariant.Check(
                type.IsInputType(),
                $"Must provide Input Type, cannot use: {type}");


            var inputType = type as ScalarGraphType;

            // Since value is an internally represented value, it must be serialized
            // to an externally represented value before converting into an AST.
            var serialized = inputType.Serialize(value);

            if (serialized == null)
            {
                return(null);
            }

            if (serialized is bool b)
            {
                return(new BooleanValue(b));
            }

            if (serialized is int i)
            {
                return(new IntValue(i));
            }

            if (serialized is long l)
            {
                return(new LongValue(l));
            }

            if (serialized is decimal @decimal)
            {
                return(new DecimalValue(@decimal));
            }

            if (serialized is double d)
            {
                return(new FloatValue(d));
            }

            if (serialized is DateTime time)
            {
                return(new DateTimeValue(time));
            }

            if (serialized is Uri uri)
            {
                return(new UriValue(uri));
            }

            if (serialized is DateTimeOffset offset)
            {
                return(new DateTimeOffsetValue(offset));
            }

            if (serialized is TimeSpan span)
            {
                return(new TimeSpanValue(span));
            }

            if (serialized is string)
            {
                if (type is EnumerationGraphType)
                {
                    return(new EnumValue(serialized.ToString()));
                }

                return(new StringValue(serialized.ToString()));
            }

            var converter = schema.FindValueConverter(serialized, type);

            if (converter != null)
            {
                return(converter.Convert(serialized, type));
            }

            throw new ExecutionError($"Cannot convert value to AST: {serialized}");
        }