Skip to content

Commit

Permalink
Allow to enumerate variables (#2833)
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelstaib authored Jan 7, 2021
1 parent 62af860 commit 6b21001
Show file tree
Hide file tree
Showing 19 changed files with 136 additions and 84 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System.Diagnostics.CodeAnalysis;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;

#nullable enable

Expand All @@ -7,7 +9,7 @@ namespace HotChocolate.Execution
/// <summary>
/// Represents a collection of coerced variables.
/// </summary>
public interface IVariableValueCollection
public interface IVariableValueCollection : IEnumerable<VariableValue>
{
/// <summary>
/// Gets a coerced variable value from the collection.
Expand All @@ -34,6 +36,6 @@ public interface IVariableValueCollection
/// <c>true</c> if a coerced variable exists and can be converted
/// to the requested type; otherwise, <c>false</c> will be returned.
/// </returns>
bool TryGetVariable<T>(NameString name, [NotNullWhen(true)]out T value);
bool TryGetVariable<T>(NameString name, [NotNullWhen(true)] out T value);
}
}
34 changes: 34 additions & 0 deletions src/HotChocolate/Core/src/Abstractions/Execution/VariableValue.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System;
using HotChocolate.Language;
using HotChocolate.Types;

namespace HotChocolate.Execution
{
/// <summary>
/// Represents a variable value.
/// </summary>
public readonly struct VariableValue
{
public VariableValue(NameString name, IInputType type, IValueNode value)
{
Name = name.EnsureNotEmpty(nameof(name));
Type = type ?? throw new ArgumentNullException(nameof(type));
Value = value ?? throw new ArgumentNullException(nameof(value));
}

/// <summary>
/// Gets the variable name.
/// </summary>
public NameString Name { get; }

/// <summary>
/// Gets the variable type.
/// </summary>
public IInputType Type { get; }

/// <summary>
/// Gets the variable value.
/// </summary>
public IValueNode Value { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace HotChocolate.Execution.Pipeline
{
internal sealed class OperationVariableCoercionMiddleware
{
private static readonly IReadOnlyDictionary<string, object?> _empty =
private static readonly IReadOnlyDictionary<string, object?> _empty =
new Dictionary<string, object?>();
private readonly RequestDelegate _next;
private readonly IDiagnosticEvents _diagnosticEvents;
Expand Down Expand Up @@ -37,7 +37,7 @@ public async ValueTask InvokeAsync(IRequestContext context)
}
else
{
var coercedValues = new Dictionary<string, VariableValue>();
var coercedValues = new Dictionary<string, VariableValueOrLiteral>();

_coercionHelper.CoerceVariableValues(
context.Schema,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public void CoerceVariableValues(
ISchema schema,
IReadOnlyList<VariableDefinitionNode> variableDefinitions,
IReadOnlyDictionary<string, object?> values,
IDictionary<string, VariableValue> coercedValues)
IDictionary<string, VariableValueOrLiteral> coercedValues)
{
if (schema is null)
{
Expand Down Expand Up @@ -52,7 +52,7 @@ public void CoerceVariableValues(
{
throw ThrowHelper.NonNullVariableIsNull(variableDefinition);
}
coercedValues[variableName] = new VariableValue(
coercedValues[variableName] = new VariableValueOrLiteral(
variableType, null, NullValueNode.Default);
}
else
Expand All @@ -63,7 +63,7 @@ public void CoerceVariableValues(
}
}

private static VariableValue CoerceVariableValue(
private static VariableValueOrLiteral CoerceVariableValue(
VariableDefinitionNode variableDefinition,
IInputType variableType,
object value)
Expand All @@ -75,7 +75,7 @@ private static VariableValue CoerceVariableValue(
// we are ensuring here that enum values are correctly specified.
valueLiteral = Rewrite(variableType, valueLiteral);

return new VariableValue(
return new VariableValueOrLiteral(
variableType,
variableType.ParseLiteral(valueLiteral),
valueLiteral);
Expand All @@ -88,7 +88,7 @@ private static VariableValue CoerceVariableValue(

if (variableType.TryDeserialize(value, out object? deserialized))
{
return new VariableValue(
return new VariableValueOrLiteral(
variableType,
deserialized,
variableType.ParseResult(value));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using HotChocolate.Language;
using HotChocolate.Types;

namespace HotChocolate.Execution.Processing
{
internal class VariableValueCollection : IVariableValueCollection
{
private readonly Dictionary<string, VariableValue> _coercedValues;
private readonly Dictionary<string, VariableValueOrLiteral> _coercedValues;

public VariableValueCollection(Dictionary<string, VariableValue> coercedValues)
public VariableValueCollection(Dictionary<string, VariableValueOrLiteral> coercedValues)
{
_coercedValues = coercedValues;
}

public static VariableValueCollection Empty { get; } =
new(new Dictionary<string, VariableValueOrLiteral>());

public T GetVariable<T>(NameString name)
{
if (TryGetVariable(name, out T value))
Expand All @@ -30,7 +35,7 @@ public T GetVariable<T>(NameString name)

public bool TryGetVariable<T>(NameString name, [NotNullWhen(true)] out T value)
{
if (_coercedValues.TryGetValue(name.Value, out VariableValue variableValue))
if (_coercedValues.TryGetValue(name.Value, out VariableValueOrLiteral variableValue))
{
if (typeof(IValueNode).IsAssignableFrom(typeof(T)))
{
Expand Down Expand Up @@ -58,7 +63,7 @@ public bool TryGetVariable<T>(NameString name, [NotNullWhen(true)] out T value)
return true;
}

if (variableValue.ValueLiteral is { })
if (variableValue.ValueLiteral is not null)
{
object? temp = variableValue.Type.ParseLiteral(variableValue.ValueLiteral);
if (temp is T casted2)
Expand All @@ -74,7 +79,19 @@ public bool TryGetVariable<T>(NameString name, [NotNullWhen(true)] out T value)
return false;
}

public static VariableValueCollection Empty { get; } =
new VariableValueCollection(new Dictionary<string, VariableValue>());
public IEnumerator<VariableValue> GetEnumerator()
{
foreach (KeyValuePair<string, VariableValueOrLiteral> item in _coercedValues)
{
IInputType type = item.Value.Type;
IValueNode value = item.Value.ValueLiteral ?? type.ParseValue(item.Value.Value);
yield return new VariableValue(item.Key, type, value);
}
}

IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

namespace HotChocolate.Execution.Processing
{
public readonly struct VariableValue
internal readonly struct VariableValueOrLiteral
{
public VariableValue(
public VariableValueOrLiteral(
IInputType type,
object? value,
IValueNode? valueLiteral)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public void VariableCoercionHelper_Schema_Is_Null()
};

var variableValues = new Dictionary<string, object>();
var coercedValues = new Dictionary<string, VariableValue>();
var coercedValues = new Dictionary<string, VariableValueOrLiteral>();

var helper = new VariableCoercionHelper();

Expand All @@ -46,7 +46,7 @@ public void VariableCoercionHelper_VariableDefinitions_Is_Null()
// arrange
ISchema schema = SchemaBuilder.New().AddStarWarsTypes().Create();
var variableValues = new Dictionary<string, object>();
var coercedValues = new Dictionary<string, VariableValue>();
var coercedValues = new Dictionary<string, VariableValueOrLiteral>();
var helper = new VariableCoercionHelper();

// act
Expand All @@ -73,7 +73,7 @@ public void VariableCoercionHelper_VariableValues_Is_Null()
Array.Empty<DirectiveNode>())
};

var coercedValues = new Dictionary<string, VariableValue>();
var coercedValues = new Dictionary<string, VariableValueOrLiteral>();

var helper = new VariableCoercionHelper();

Expand Down Expand Up @@ -130,7 +130,7 @@ public void Coerce_Nullable_String_Variable_With_Default_Where_Value_Is_Not_Prov
};

var variableValues = new Dictionary<string, object>();
var coercedValues = new Dictionary<string, VariableValue>();
var coercedValues = new Dictionary<string, VariableValueOrLiteral>();

var helper = new VariableCoercionHelper();

Expand Down Expand Up @@ -169,7 +169,7 @@ public void Coerce_Nullable_String_Variable_With_Default_Where_Value_Is_Provided
{"abc", new StringValueNode("xyz")}
};

var coercedValues = new Dictionary<string, VariableValue>();
var coercedValues = new Dictionary<string, VariableValueOrLiteral>();

var helper = new VariableCoercionHelper();

Expand Down Expand Up @@ -208,7 +208,7 @@ public void Coerce_Nullable_String_Variable_With_Default_Where_Plain_Value_Is_Pr
{"abc", "xyz"}
};

var coercedValues = new Dictionary<string, VariableValue>();
var coercedValues = new Dictionary<string, VariableValueOrLiteral>();

var helper = new VariableCoercionHelper();

Expand Down Expand Up @@ -247,7 +247,7 @@ public void Coerce_Nullable_String_Variable_With_Default_Where_Null_Is_Provided(
{"abc", NullValueNode.Default}
};

var coercedValues = new Dictionary<string, VariableValue>();
var coercedValues = new Dictionary<string, VariableValueOrLiteral>();

var helper = new VariableCoercionHelper();

Expand Down Expand Up @@ -286,7 +286,7 @@ public void Coerce_Nullable_String_Variable_With_Default_Where_Plain_Null_Is_Pro
{"abc", null}
};

var coercedValues = new Dictionary<string, VariableValue>();
var coercedValues = new Dictionary<string, VariableValueOrLiteral>();

var helper = new VariableCoercionHelper();

Expand Down Expand Up @@ -325,7 +325,7 @@ public void Coerce_Nullable_ReviewInput_Variable_With_Object_Literal()
{"abc", new ObjectValueNode(new ObjectFieldNode("stars", 5))}
};

var coercedValues = new Dictionary<string, VariableValue>();
var coercedValues = new Dictionary<string, VariableValueOrLiteral>();

var helper = new VariableCoercionHelper();

Expand Down Expand Up @@ -364,7 +364,7 @@ public void Coerce_Nullable_ReviewInput_Variable_With_Dictionary()
{"abc", new Dictionary<string, object> { {"stars", 5} }}
};

var coercedValues = new Dictionary<string, VariableValue>();
var coercedValues = new Dictionary<string, VariableValueOrLiteral>();

var helper = new VariableCoercionHelper();

Expand Down Expand Up @@ -403,7 +403,7 @@ public void Coerce_Nullable_ReviewInput_Variable_With_Review_Object()
{ "abc", new Review { Stars = 5 } }
};

var coercedValues = new Dictionary<string, VariableValue>();
var coercedValues = new Dictionary<string, VariableValueOrLiteral>();

var helper = new VariableCoercionHelper();

Expand Down Expand Up @@ -442,7 +442,7 @@ public void Error_When_Value_Is_Null_On_Non_Null_Variable()
{"abc", NullValueNode.Default}
};

var coercedValues = new Dictionary<string, VariableValue>();
var coercedValues = new Dictionary<string, VariableValueOrLiteral>();

var helper = new VariableCoercionHelper();

Expand Down Expand Up @@ -475,7 +475,7 @@ public void Error_When_PlainValue_Is_Null_On_Non_Null_Variable()
{"abc", null}
};

var coercedValues = new Dictionary<string, VariableValue>();
var coercedValues = new Dictionary<string, VariableValueOrLiteral>();

var helper = new VariableCoercionHelper();

Expand Down Expand Up @@ -508,7 +508,7 @@ public void Error_When_Value_Type_Does_Not_Match_Variable_Type()
{"abc", new IntValueNode(1)}
};

var coercedValues = new Dictionary<string, VariableValue>();
var coercedValues = new Dictionary<string, VariableValueOrLiteral>();

var helper = new VariableCoercionHelper();

Expand Down Expand Up @@ -544,7 +544,7 @@ public void Error_When_PlainValue_Type_Does_Not_Match_Variable_Type()
{"abc", 1}
};

var coercedValues = new Dictionary<string, VariableValue>();
var coercedValues = new Dictionary<string, VariableValueOrLiteral>();

var helper = new VariableCoercionHelper();

Expand Down Expand Up @@ -577,7 +577,7 @@ public void Variable_Type_Is_Not_An_Input_Type()
{"abc", 1}
};

var coercedValues = new Dictionary<string, VariableValue>();
var coercedValues = new Dictionary<string, VariableValueOrLiteral>();

var helper = new VariableCoercionHelper();

Expand Down Expand Up @@ -610,7 +610,7 @@ public void Error_When_Input_Field_Has_Different_Properties_Than_Defined()
{ "abc", new ObjectValueNode(new ObjectFieldNode("abc", "def")) }
};

var coercedValues = new Dictionary<string, VariableValue>();
var coercedValues = new Dictionary<string, VariableValueOrLiteral>();

var helper = new VariableCoercionHelper();

Expand Down Expand Up @@ -669,7 +669,7 @@ enum TestEnum {
}
};

var coercedValues = new Dictionary<string, VariableValue>();
var coercedValues = new Dictionary<string, VariableValueOrLiteral>();

var helper = new VariableCoercionHelper();

Expand Down Expand Up @@ -731,7 +731,7 @@ enum TestEnum {
}
};

var coercedValues = new Dictionary<string, VariableValue>();
var coercedValues = new Dictionary<string, VariableValueOrLiteral>();

var helper = new VariableCoercionHelper();

Expand Down
Loading

0 comments on commit 6b21001

Please sign in to comment.