Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add char scalar to HotChocolate.Types.Scalars #7142

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 146 additions & 0 deletions src/HotChocolate/Core/src/Types.Scalars/CharType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
using System;
using System.Diagnostics.CodeAnalysis;
using HotChocolate.Language;

namespace HotChocolate.Types;

/// <summary>
/// The CharType scalar type represents a single character value.
/// </summary>
public class CharType : ScalarType<char, StringValueNode>
{
public CharType(
string name,
string? description = null,
BindingBehavior bind = BindingBehavior.Explicit)
: base(name, bind)
{
Description = description;
}

/// <summary>
/// Initializes a new instance of the <see cref="CharType"/> class.
/// </summary>
[ActivatorUtilitiesConstructor]
public CharType()
: this(
WellKnownScalarTypes.Char,
ScalarResources.CharType_Description)
{
}

/// <inheritdoc />
protected override bool IsInstanceOfType(StringValueNode valueSyntax)
{
return TryParseChar(valueSyntax.Value, out _);
}

/// <inheritdoc />
protected override char ParseLiteral(StringValueNode valueSyntax)
{
if (TryParseChar(valueSyntax.Value, out var character))
{
return character.Value;
}

throw ThrowHelper.CharType_ParseLiteral_IsInvalid(this);
}

/// <inheritdoc />
protected override StringValueNode ParseValue(char runtimeValue)
{
if (TryParseChar(runtimeValue, out var character))
{
return new StringValueNode(character.Value.ToString());
}

throw ThrowHelper.CharType_ParseValue_IsInvalid(this);
}

/// <inheritdoc />
public override IValueNode ParseResult(object? resultValue)
{
if (resultValue is null)
{
return NullValueNode.Default;
}

if (TryParseChar(resultValue, out var character))
{
return new StringValueNode(character.Value.ToString());
}

throw ThrowHelper.CharType_ParseValue_IsInvalid(this);
}

/// <inheritdoc />
public override bool TrySerialize(object? runtimeValue, out object? resultValue)
{
if (runtimeValue is null)
{
resultValue = null;
return true;
}

if (runtimeValue is char character)
{
resultValue = character;
return true;
}

if (TryParseChar(runtimeValue, out var c))
{
resultValue = c;
return true;
}

resultValue = null;
return false;
}

/// <inheritdoc />
public override bool TryDeserialize(object? resultValue, out object? runtimeValue)
{
if (resultValue is null)
{
runtimeValue = null;
return true;
}

if (resultValue is char character)
{
runtimeValue = character;
return true;
}

if (TryParseChar(resultValue, out var c))
{
runtimeValue = c;
return true;
}

runtimeValue = null;
return false;
}

/// <summary>
/// Attempts to convert the specified object to a char.
/// </summary>
/// <param name="value">The object to convert.</param>
/// <param name="character">The char value equivalent to the value parameter if the conversion succeeded, or null if the conversion failed.</param>
/// <returns>True if the conversion succeeded, otherwise false.</returns>
private static bool TryParseChar(object value, [NotNullWhen(true)] out char? character)
{
character = null;

try
{
character = Convert.ToChar(value);
return true;
}
catch (Exception)
{
return false;
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions src/HotChocolate/Core/src/Types.Scalars/ScalarResources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,15 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="CharType_Description" xml:space="preserve">
<value>The CharType scalar type represents a single character value.</value>
</data>
<data name="CharType_IsInvalid_ParseLiteral" xml:space="preserve">
<value>CharType cannot parse the provided literal. The provided value is not a valid single character.</value>
</data>
<data name="CharType_IsInvalid_ParseValue" xml:space="preserve">
<value>CharType cannot parse the provided value. The provided value is not a valid single character.</value>
</data>
<data name="EmailAddressType_Description" xml:space="preserve">
<value>The EmailAddress scalar type constitutes a valid email address, represented as a UTF-8 character sequence. The scalar follows the specification defined by the HTML Spec https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address.</value>
</data>
Expand Down
22 changes: 22 additions & 0 deletions src/HotChocolate/Core/src/Types.Scalars/ThrowHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,28 @@ namespace HotChocolate.Types;

internal static class ThrowHelper
{
public static SerializationException CharType_ParseLiteral_IsInvalid(IType type)
{
return new SerializationException(
ErrorBuilder.New()
.SetMessage(ScalarResources.CharType_IsInvalid_ParseLiteral)
.SetCode(ErrorCodes.Scalars.InvalidSyntaxFormat)
.SetExtension("actualType", WellKnownScalarTypes.Char)
.Build(),
type);
}

public static SerializationException CharType_ParseValue_IsInvalid(IType type)
{
return new SerializationException(
ErrorBuilder.New()
.SetMessage(ScalarResources.CharType_IsInvalid_ParseValue)
.SetCode(ErrorCodes.Scalars.InvalidRuntimeType)
.SetExtension("actualType", WellKnownScalarTypes.Char)
.Build(),
type);
}

public static SerializationException EmailAddressType_ParseLiteral_IsInvalid(IType type)
{
return new SerializationException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ namespace HotChocolate.Types;

internal static class WellKnownScalarTypes
{
public const string Char = nameof(Char);
public const string EmailAddress = nameof(EmailAddress);
public const string HexColor = nameof(HexColor);
public const string Hsl = nameof(Hsl);
Expand Down
Loading