Skip to content

Commit

Permalink
Rename ScalarRangeNumber to ScalarRange and correct parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
Struan Judd committed Jan 25, 2024
1 parent b411ec0 commit 42df581
Show file tree
Hide file tree
Showing 17 changed files with 111 additions and 81 deletions.
4 changes: 2 additions & 2 deletions src/GqlPlus.Verifier/Ast/Schema/ScalarDeclAst.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ string Description
public string? EnumType { get; set; }
public ScalarMemberEnumAst[] Enums { get; set; } = [];

public ScalarRangeNumberAst[] Numbers { get; set; } = [];
public ScalarRangeAst[] Numbers { get; set; } = [];
public ScalarRegexAst[] Regexes { get; set; } = [];
public ScalarReferenceAst[] References { get; set; } = [];

Expand All @@ -24,7 +24,7 @@ string Description
public ScalarDeclAstOld(TokenAt at, string name)
: this(at, name, "") { }

public ScalarDeclAstOld(TokenAt at, string name, ScalarRangeNumberAst[] numbers)
public ScalarDeclAstOld(TokenAt at, string name, ScalarRangeAst[] numbers)
: this(at, name, "")
=> Numbers = numbers;
public ScalarDeclAstOld(TokenAt at, string name, string enumType, ScalarMemberEnumAst[] enums)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@

namespace GqlPlus.Verifier.Ast.Schema;

public sealed record class ScalarRangeNumberAst(TokenAt At, bool Excludes)
: AstScalarMember(At, Excludes), IEquatable<ScalarRangeNumberAst>
public sealed record class ScalarRangeAst(TokenAt At, bool Excludes)
: AstScalarMember(At, Excludes), IEquatable<ScalarRangeAst>
{
public decimal? Lower { get; set; }
public decimal? Upper { get; set; }

internal override string Abbr => "SR";

public ScalarRangeNumberAst(TokenAt at, bool excludes, decimal? lower, decimal? upper)
public ScalarRangeAst(TokenAt at, bool excludes, decimal? lower, decimal? upper)
: this(at, excludes)
=> (Lower, Upper) = (lower, upper);

public bool Equals(ScalarRangeNumberAst? other)
public bool Equals(ScalarRangeAst? other)
=> base.Equals(other)
&& Lower.NullEqual(other.Lower)
&& Upper.NullEqual(other.Upper);
Expand Down
2 changes: 1 addition & 1 deletion src/GqlPlus.Verifier/BuiltIn.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ internal static class BuiltIn
new EnumDeclAst(AstNulls.At, "Unit") { Aliases = ["_"], Members = [new(AstNulls.At, "_")] },

new ScalarDeclEnumAst(AstNulls.At, "Enum", "", []),
new AstScalar<ScalarRangeNumberAst>(AstNulls.At, "Number", ScalarKind.Number, []) { Aliases = ["0"] },
new AstScalar<ScalarRangeAst>(AstNulls.At, "Number", ScalarKind.Number, []) { Aliases = ["0"] },
new AstScalar<ScalarRegexAst>(AstNulls.At, "String", ScalarKind.String, []) { Aliases = ["*"] },
];

Expand Down
4 changes: 2 additions & 2 deletions src/GqlPlus.Verifier/Merging/AllMergers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ public static IServiceCollection AddMergers(this IServiceCollection services)
.AddMergeAll<AstType, EnumDeclAst, MergeEnums>()
.AddMerge<EnumMemberAst, MergeEnumMembers>()
.AddMergeAll<AstType, AstScalar, MergeAllScalars>()
.AddMergeScalar<ScalarRangeNumberAst>()
.AddMergeScalar<ScalarRangeAst>()
.AddMergeScalar<ScalarRegexAst>()
.AddMergeScalar<ScalarReferenceAst>()
.AddMerge<ScalarRangeNumberAst, MergeScalarRanges>()
.AddMerge<ScalarRangeAst, MergeScalarRanges>()
.AddMerge<ScalarRegexAst, MergeScalarRegexes>()
.AddMerge<ScalarReferenceAst, MergeScalarReferences>()
// Object types
Expand Down
2 changes: 1 addition & 1 deletion src/GqlPlus.Verifier/Merging/MergeScalarRanges.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
namespace GqlPlus.Verifier.Merging;

internal class MergeScalarRanges
: BaseMerger<ScalarRangeNumberAst>
: BaseMerger<ScalarRangeAst>
{
}
4 changes: 2 additions & 2 deletions src/GqlPlus.Verifier/Modelling/ScalarModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ internal override RenderStructure Render()
}

internal class ScalarNumberModeller
: ModellerBase<AstScalar<ScalarRangeNumberAst>, ModelBaseScalar>
: ModellerBase<AstScalar<ScalarRangeAst>, ModelBaseScalar>
{
internal override ModelBaseScalar ToModel(AstScalar<ScalarRangeNumberAst> ast)
internal override ModelBaseScalar ToModel(AstScalar<ScalarRangeAst> ast)
=> new ScalarNumberModel(ast.Name) {
Aliases = ast.Aliases,
Description = ast.Description,
Expand Down
34 changes: 22 additions & 12 deletions src/GqlPlus.Verifier/Parse/Schema/ParseScalar.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Diagnostics.CodeAnalysis;

using GqlPlus.Verifier.Ast;
using GqlPlus.Verifier.Ast.Schema;
using GqlPlus.Verifier.Result;
Expand All @@ -15,18 +16,22 @@ Parser<ScalarDefinition>.D definition
) : DeclarationParser<ScalarDefinition, AstScalar>(name, param, aliases, option, definition)
{
protected override AstScalar MakeResult(AstScalar partial, ScalarDefinition value)
=> value.Kind switch {
ScalarKind.Number => new AstScalar<ScalarRangeNumberAst>(partial.At, partial.Name, value.Kind, value.Numbers) {
=> value.Kind switch
{
ScalarKind.Number => new AstScalar<ScalarRangeAst>(partial.At, partial.Name, value.Kind, value.Numbers)
{
Aliases = partial.Aliases,
Description = partial.Description,
Extends = value.Extends
},
ScalarKind.String => new AstScalar<ScalarRegexAst>(partial.At, partial.Name, value.Kind, value.Regexes) {
ScalarKind.String => new AstScalar<ScalarRegexAst>(partial.At, partial.Name, value.Kind, value.Regexes)
{
Aliases = partial.Aliases,
Description = partial.Description,
Extends = value.Extends
},
ScalarKind.Union => new AstScalar<ScalarReferenceAst>(partial.At, partial.Name, value.Kind, value.References) {
ScalarKind.Union => new AstScalar<ScalarReferenceAst>(partial.At, partial.Name, value.Kind, value.References)
{
Aliases = partial.Aliases,
Description = partial.Description,
Extends = value.Extends
Expand All @@ -46,20 +51,20 @@ internal class ScalarDefinition
{
public ScalarKind Kind { get; set; } = ScalarKind.Number;
public string? Extends { get; set; }
public ScalarRangeNumberAst[] Numbers { get; set; } = [];
public ScalarRangeAst[] Numbers { get; set; } = [];
public ScalarRegexAst[] Regexes { get; set; } = [];
public ScalarReferenceAst[] References { get; set; } = [];
}

internal class ParseScalarDefinition(
Parser<IEnumParser<ScalarKind>, ScalarKind>.D kind,
Parser<ScalarRangeNumberAst>.DA numbers,
Parser<ScalarRangeAst>.DA numbers,
Parser<ScalarReferenceAst>.DA references,
Parser<ScalarRegexAst>.DA regexes
) : Parser<ScalarDefinition>.I
{
private readonly Parser<IEnumParser<ScalarKind>, ScalarKind>.L _kind = kind;
private readonly Parser<ScalarRangeNumberAst>.LA _numbers = numbers;
private readonly Parser<ScalarRangeAst>.LA _numbers = numbers;
private readonly Parser<ScalarReferenceAst>.LA _references = references;
private readonly Parser<ScalarRegexAst>.LA _regexes = regexes;

Expand All @@ -69,28 +74,33 @@ public IResult<ScalarDefinition> Parse<TContext>(TContext tokens, string label)
ScalarDefinition result = new();

var scalarKind = _kind.I.Parse(tokens, label);
if (!scalarKind.Required(kind => result.Kind = kind)) {
if (!scalarKind.Required(kind => result.Kind = kind))
{
return scalarKind.AsResult(result);
}

switch (result.Kind) {
switch (result.Kind)
{
case ScalarKind.Number:
var scalarRanges = _numbers.Parse(tokens, label);
if (scalarRanges.Required(ranges => result.Numbers = ranges)) {
if (scalarRanges.Required(ranges => result.Numbers = ranges))
{
return tokens.End(label, () => result);
}

return scalarRanges.AsResult(result);
case ScalarKind.String:
var scalarRegexes = _regexes.Parse(tokens, label);
if (scalarRegexes.Required(regexes => result.Regexes = regexes)) {
if (scalarRegexes.Required(regexes => result.Regexes = regexes))
{
return tokens.End(label, () => result);
}

return scalarRegexes.AsResult(result);
case ScalarKind.Union:
var scalarReferences = _references.Parse(tokens, label);
if (scalarReferences.Required(references => result.References = references)) {
if (scalarReferences.Required(references => result.References = references))
{
return tokens.End(label, () => result);
}

Expand Down
42 changes: 27 additions & 15 deletions src/GqlPlus.Verifier/Parse/Schema/ParseScalarRange.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,47 @@

namespace GqlPlus.Verifier.Parse.Schema;

internal class ParseScalarRange : Parser<ScalarRangeNumberAst>.I
internal class ParseScalarRange : Parser<ScalarRangeAst>.I
{
public IResult<ScalarRangeNumberAst> Parse<TContext>(TContext tokens, string label)
public IResult<ScalarRangeAst> Parse<TContext>(TContext tokens, string label)
where TContext : Tokenizer
{
var at = tokens.At;
var excludes = tokens.Take('!');

var range = new ScalarRangeNumberAst(at, excludes);
var range = new ScalarRangeAst(at, excludes);
var isUpper = tokens.Take('<');
var hasLower = tokens.Number(out var min);
var hasRange = tokens.Take('~');
if (hasLower && !hasRange) {
return tokens.Error(label, "range operator ('~')", range);

if (isUpper) {
range.Upper = min;
return hasLower
? range.Ok()
: tokens.Error(label, "upper bound after '<'", range);
}

var hasUpper = tokens.Number(out var max);
range.Lower = min;
if (tokens.Take('>')) {
return hasLower
? range.Ok()
: tokens.Error(label, "lower bound before '>'", range);
}

if (hasLower) {
range.Lower = min;
if (!tokens.Take('~')) {
range.Upper = min;
return hasLower
? range.Ok()
: range.Empty();
}

if (hasUpper) {
range.Upper = max;
if (!hasLower) {
return tokens.Error(label, "lower bound before '~'", range);
}

return hasLower || hasUpper
var hasUpper = tokens.Number(out var max);
range.Upper = max;
return hasUpper
? range.Ok()
: hasRange
? tokens.Error(label, "min or max bounds", range)
: range.Empty();
: tokens.Error(label, "upper bound after '~'", range);
}
}
2 changes: 1 addition & 1 deletion src/GqlPlus.Verifier/Parse/Schema/SchemaParsers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public static IServiceCollection AddSchemaParsers(this IServiceCollection servic
// Scalar
.AddParser<ScalarDefinition, ParseScalarDefinition>()
.AddEnum<ScalarKind>()
.AddArrayParser<ScalarRangeNumberAst, ParseScalarRange>()
.AddArrayParser<ScalarRangeAst, ParseScalarRange>()
.AddArrayParser<ScalarRegexAst, ParseScalarRegex>()
.AddArrayParser<ScalarReferenceAst, ParseScalarReference>()
.AddDeclarationParser<AstScalar, ParseScalar>("scalar")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,40 @@ public class ScalarAstNumberTests
[Theory, RepeatData(Repeats)]
public void HashCode_WithRanges(string name, MemberInput<decimal> input)
=> _checks.HashCode(
() => ScalarNumber(name, input.ScalarMembers(ScalarRangeNumber)));
() => ScalarNumber(name, input.ScalarMembers(ScalarRange)));

[Theory, RepeatData(Repeats)]
public void String_WithRanges(string name, MemberInput<decimal> input)
=> _checks.String(
() => ScalarNumber(name, input.ScalarMembers(ScalarRangeNumber)),
() => ScalarNumber(name, input.ScalarMembers(ScalarRange)),
$"( !S {name} Number !SR < {input.Lower} !SR ! {input.Lower} ~ {input.Upper} !SR {input.Upper} > )");

[Theory, RepeatData(Repeats)]
public void Equality_WithRanges(string name, MemberInput<decimal> input)
=> _checks.Equality(
() => ScalarNumber(name, input.ScalarMembers(ScalarRangeNumber)));
() => ScalarNumber(name, input.ScalarMembers(ScalarRange)));

[Theory, RepeatData(Repeats)]
public void Inequality_BetweenRanges(string name, MemberInput<decimal> input1, MemberInput<decimal> input2)
=> _checks.InequalityBetween(input1, input2,
input => ScalarNumber(name, input.ScalarMembers(ScalarRangeNumber)),
input => ScalarNumber(name, input.ScalarMembers(ScalarRange)),
input1 == input2);

protected override string AliasesString(string input, string aliases)
=> $"( !S {input}{aliases} Number )";

private readonly AstAliasedChecks<AstScalar<ScalarRangeNumberAst>> _checks
private readonly AstAliasedChecks<AstScalar<ScalarRangeAst>> _checks
= new(name => ScalarNumber(name, []));

internal override IAstAliasedChecks<string> AliasedChecks => _checks;

private static ScalarRangeNumberAst ScalarRangeNumber(decimal lower, decimal upper, bool? rightNull)
private static ScalarRangeAst ScalarRange(decimal lower, decimal upper, bool? rightNull)
=> rightNull switch {
false => new(AstNulls.At, false, null, upper),
true => new(AstNulls.At, false, lower, null),
_ => new(AstNulls.At, false, lower, upper),
};

private static AstScalar<ScalarRangeNumberAst> ScalarNumber(string name, ScalarRangeNumberAst[] list)
private static AstScalar<ScalarRangeAst> ScalarNumber(string name, ScalarRangeAst[] list)
=> new(AstNulls.At, name, ScalarKind.Number, list);
}
4 changes: 2 additions & 2 deletions test/GqlPlus.Verifier.ClassTests/Ast/Schema/ScalarAstTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ public class ScalarAstTests : AstAliasedTests
protected override string AliasesString(string input, string aliases)
=> $"( !S {input}{aliases} Number )";

private readonly AstAliasedChecks<AstScalar<ScalarRangeNumberAst>> _checks
= new(name => new AstScalar<ScalarRangeNumberAst>(AstNulls.At, name, ScalarKind.Number, []));
private readonly AstAliasedChecks<AstScalar<ScalarRangeAst>> _checks
= new(name => new AstScalar<ScalarRangeAst>(AstNulls.At, name, ScalarKind.Number, []));

internal override IAstAliasedChecks<string> AliasedChecks => _checks;
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
namespace GqlPlus.Verifier.Ast.Schema;

public class ScalarRangeNumberAstTests
: AstAbbreviatedTests<RangeNumberInput>
public class ScalarRangeAstTests
: AstAbbreviatedTests<RangeInput>
{
protected override string AbbreviatedString(RangeNumberInput input)
protected override string AbbreviatedString(RangeInput input)
=> $"( !SR {input} )";

private readonly AstAbbreviatedChecks<RangeNumberInput, ScalarRangeNumberAst> _checks
= new(input => new ScalarRangeNumberAst(AstNulls.At, false, input.Lower, input.Upper));
private readonly AstAbbreviatedChecks<RangeInput, ScalarRangeAst> _checks
= new(input => new ScalarRangeAst(AstNulls.At, false, input.Lower, input.Upper));

internal override IAstAbbreviatedChecks<RangeNumberInput> AbbreviatedChecks => _checks;
internal override IAstAbbreviatedChecks<RangeInput> AbbreviatedChecks => _checks;
}

public record struct RangeNumberInput(decimal? Min, decimal? Max)
public record struct RangeInput(decimal? Min, decimal? Max)
{
internal readonly decimal? Lower => Max < Min ? Max : Min;
internal readonly decimal? Upper => Max < Min ? Min : Max;
Expand All @@ -34,6 +34,6 @@ public override readonly string ToString()
return result;
}

public readonly ScalarRangeNumberAst[] ScalarRanges()
=> new ScalarRangeNumberAst[] { new(AstNulls.At, false, Lower, Upper) };
public readonly ScalarRangeAst[] ScalarRanges()
=> new ScalarRangeAst[] { new(AstNulls.At, false, Lower, Upper) };
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace GqlPlus.Verifier.Merging;

public class MergeScalarNumbersTests
: TestDescriptions<AstScalar<ScalarRangeNumberAst>>
: TestDescriptions<AstScalar<ScalarRangeAst>>
{
[Theory, RepeatData(Repeats)]
public void CanMerge_TwoItemsSameKinds_ReturnsTrue(string name)
Expand All @@ -28,7 +28,7 @@ public void CanMerge_TwoItemsDifferentKinds_ReturnsFalse(string name)
}

[Theory, RepeatData(Repeats)]
public void CanMerge_TwoItemsRangesCantMerge_ReturnsFalse(string name, RangeNumberInput range)
public void CanMerge_TwoItemsRangesCantMerge_ReturnsFalse(string name, RangeInput range)
{
var items = new[] {
MakeDescribed(name) with { Members = range.ScalarRanges() },
Expand All @@ -41,18 +41,18 @@ public void CanMerge_TwoItemsRangesCantMerge_ReturnsFalse(string name, RangeNumb
result.Should().BeFalse();
}

private readonly IMerge<ScalarRangeNumberAst> _ranges;
private readonly MergeScalars<ScalarRangeNumberAst> _merger;
private readonly IMerge<ScalarRangeAst> _ranges;
private readonly MergeScalars<ScalarRangeAst> _merger;

public MergeScalarNumbersTests()
{
_ranges = Merger<ScalarRangeNumberAst>();
_ranges = Merger<ScalarRangeAst>();

_merger = new(_ranges);
}

protected override GroupsMerger<AstScalar<ScalarRangeNumberAst>> MergerGroups => _merger;
protected override GroupsMerger<AstScalar<ScalarRangeAst>> MergerGroups => _merger;

protected override AstScalar<ScalarRangeNumberAst> MakeDescribed(string name, string description = "")
protected override AstScalar<ScalarRangeAst> MakeDescribed(string name, string description = "")
=> new(AstNulls.At, name, description, ScalarKind.Number);
}
Loading

0 comments on commit 42df581

Please sign in to comment.