Skip to content

Commit

Permalink
Fixing Default values (#111)
Browse files Browse the repository at this point in the history
* Init

* Fixes #110 Making default values work
  • Loading branch information
Ethan Celletti authored Feb 2, 2023
1 parent f17eba0 commit 1f559b6
Show file tree
Hide file tree
Showing 9 changed files with 233 additions and 100 deletions.
10 changes: 10 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[*]
charset = utf-8
end_of_line = lf

[*.{cs,razor}]
dotnet_style_qualification_for_property = true:error
dotnet_style_qualification_for_field = true:error
dotnet_style_qualification_for_event = true:error
dotnet_style_qualification_for_method = true:error
indent_style = tab
15 changes: 8 additions & 7 deletions EdjCase.JsonRpc.sln
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29324.140
# Visual Studio Version 17
VisualStudioVersion = 17.4.33103.184
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{EB6CC2D7-ED2C-447F-A85B-5E204FD69352}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{41AD7143-8434-4ABE-92B7-70F448CFE634}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
Nuget.config = Nuget.config
EndProjectSection
EndProject
Expand All @@ -31,11 +32,6 @@ EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EdjCase.JsonRpc.Router.Swagger", "src\EdjCase.JsonRpc.Router.Swagger\EdjCase.JsonRpc.Router.Swagger.csproj", "{93369553-1DA3-47A1-B46B-23858B68099D}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
src\EdjCase.JsonRpc.Common\EdjCase.JsonRpc.Common.projitems*{1546452e-2db4-421c-90cd-b4b310ce9ad9}*SharedItemsImports = 13
src\EdjCase.JsonRpc.Common\EdjCase.JsonRpc.Common.projitems*{87ed8b44-b59a-440c-a377-565effb2691a}*SharedItemsImports = 5
src\EdjCase.JsonRpc.Common\EdjCase.JsonRpc.Common.projitems*{f89e9e51-0d7a-4a82-a899-14c886c4f384}*SharedItemsImports = 5
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
Expand Down Expand Up @@ -91,4 +87,9 @@ Global
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {297BE26F-B61D-4A43-9A84-2442133FD45E}
EndGlobalSection
GlobalSection(SharedMSBuildProjectFiles) = preSolution
src\EdjCase.JsonRpc.Common\EdjCase.JsonRpc.Common.projitems*{1546452e-2db4-421c-90cd-b4b310ce9ad9}*SharedItemsImports = 13
src\EdjCase.JsonRpc.Common\EdjCase.JsonRpc.Common.projitems*{87ed8b44-b59a-440c-a377-565effb2691a}*SharedItemsImports = 5
src\EdjCase.JsonRpc.Common\EdjCase.JsonRpc.Common.projitems*{f89e9e51-0d7a-4a82-a899-14c886c4f384}*SharedItemsImports = 5
EndGlobalSection
EndGlobal
130 changes: 71 additions & 59 deletions src/EdjCase.JsonRpc.Router/Defaults/DefaultRpcInvoker.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
Expand Down Expand Up @@ -190,68 +190,72 @@ private object[] ParseParameters(TopLevelRpcParameters? requestParameters, IRead
object[] paramCache = ArrayPool<object>.Shared.Rent(methodParameters.Count);
try
{
if (requestParameters != null && requestParameters.Any())
if (requestParameters == null || !requestParameters.Any())
{
// Create missing values array
return Enumerable.Repeat(Type.Missing, methodParameters.Count).ToArray();
}
RpcParameter[] requestParameterArray;
if (requestParameters.IsDictionary)
{
RpcParameter[] parameterList;
if (requestParameters.IsDictionary)
if (!this.TryParseParameterList(methodParameters, requestParameters.AsDictionary, out RpcParameter[]? pList))
{
if (!this.TryParseParameterList(methodParameters, requestParameters.AsDictionary, out RpcParameter[]? pList))
{
string message = "Unable to parse the parameter dictionary as a list";
throw new RpcException(RpcErrorCode.InternalError, message);
}
parameterList = pList!;
string message = "Unable to parse the parameter dictionary as a list";
throw new RpcException(RpcErrorCode.InternalError, message);
}
else
{
parameterList = requestParameters.AsArray;
}
List<IRpcParameterInfo>? badParams = null;

Exception? exception = null;

for (int i = 0; i < parameterList!.Length; i++)
{
IRpcParameterInfo parameterInfo = methodParameters[i];
RpcParameter parameter = parameterList[i];
RpcParameterType type = this.parameterConverter.GetRpcParameterType(parameterInfo.RawType);
bool matches = this.parameterConverter.TryConvertValue(parameter, type, parameterInfo.RawType, out object? value, out exception);
if (!matches)
{
if (badParams == null)
{
int parametersRemaining = parameterList.Length - i;
badParams = new List<IRpcParameterInfo>(parametersRemaining);
}
badParams.Add(parameterInfo);
continue;
}
paramCache[i] = value!;
}
if (badParams != null)
requestParameterArray = pList!;
}
else
{
requestParameterArray = requestParameters.AsArray;
}
List<IRpcParameterInfo>? badParams = null;

Exception? exception = null;

for (int i = 0; i < requestParameterArray!.Length; i++)
{
IRpcParameterInfo parameterInfo = methodParameters[i];
RpcParameter requsetParam = requestParameterArray[i];
RpcParameterType type = this.parameterConverter.GetRpcParameterType(parameterInfo.RawType);
bool matches = this.parameterConverter.TryConvertValue(requsetParam, type, parameterInfo.RawType, out object? value, out exception);
if (!matches)
{
string message = string.Join(
"\n",
badParams.Select(p => $"Unable to parse parameter '{p.Name}' to type '{p.RawType}'"));

if (exception != null)
if (badParams == null)
{
message = $"{message},\n{exception.Message}";
int parametersRemaining = requestParameterArray.Length - i;
badParams = new List<IRpcParameterInfo>(parametersRemaining);
}

throw new RpcException(RpcErrorCode.InvalidParams, message);
badParams.Add(parameterInfo);
continue;
}
//Only make an array if needed
var deserializedParameters = new object[methodParameters.Count];
paramCache
.AsSpan(0, methodParameters.Count)
.CopyTo(deserializedParameters);
return deserializedParameters;
paramCache[i] = value!;
}
else
if (badParams != null)
{
return new object[methodParameters.Count];
string message = string.Join(
"\n",
badParams.Select(p => $"Unable to parse parameter '{p.Name}' to type '{p.RawType}'"));

if (exception != null)
{
message = $"{message},\n{exception.Message}";
}

throw new RpcException(RpcErrorCode.InvalidParams, message);
}
//Only make an array if needed
var deserializedParameters = new object[methodParameters.Count];
paramCache
.AsSpan(0, requestParameterArray.Length)
.CopyTo(deserializedParameters);
int missingParametersCount = methodParameters.Count - requestParameterArray.Length;
if (missingParametersCount > 0)
{
// If missing, fill missing with Type.Missing value for invokation
Array.Fill(deserializedParameters, Type.Missing, requestParameterArray.Length, missingParametersCount);
}
return deserializedParameters;
}
finally
{
Expand All @@ -278,17 +282,25 @@ private bool TryParseParameterList(IReadOnlyList<IRpcParameterInfo> methodParame
foreach (KeyValuePair<string, RpcParameter> requestParameter in requestParameters)
{
if (RpcUtil.NamesMatch(parameterInfo.Name.AsSpan(), requestParameter.Key.AsSpan()))
{
//TODO do we care about the case where 2+ parameters have very similar names and types?
{
//TODO do we care about the case where 2+ parameters have very similar names and types?
parameterList[i] = requestParameter.Value;
break;
}
}
if (parameterList[i] == null)
{
//Doesn't match the names of any
return false;
if (parameterList[i] != null)
{
// If found a match, continue
continue;
}
if (!parameterInfo.IsOptional)
{
// If there is no specified matching param and the method param
// is not optional, fail the matching
return false;
}
// Set an unspecified value if its optional
parameterList[i] = RpcParameter.Null(isSpecified: false);
}
return true;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using EdjCase.JsonRpc.Router.Abstractions;
using EdjCase.JsonRpc.Router.Abstractions;
using EdjCase.JsonRpc.Router.Utilities;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
Expand Down Expand Up @@ -30,7 +30,15 @@ public bool TryConvertValue(
Type destinationRawType,
out object? destinationValue,
out Exception? exception)
{
{
if(sourceValue.Type == RpcParameterType.Null
&& !sourceValue.GetIfNullIsSpecified())
{
// Any unspecified type is 'missing'
destinationValue = Type.Missing;
exception = null;
return true;
}
TryConvertFunc? func = this.TryGetConveterFunc(sourceValue.Type, destinationType);
if (func == null)
{
Expand Down Expand Up @@ -92,10 +100,10 @@ public Context(
ILogger<DefaultRpcParameterConverter> logger,
JsonSerializerOptions? serializerOptions)
{
SourceValue = sourceValue ?? throw new ArgumentNullException(nameof(sourceValue));
DestinationType = destinationType ?? throw new ArgumentNullException(nameof(destinationType));
Logger = logger ?? throw new ArgumentNullException(nameof(logger));
SerializerOptions = serializerOptions;
this.SourceValue = sourceValue ?? throw new ArgumentNullException(nameof(sourceValue));
this.DestinationType = destinationType ?? throw new ArgumentNullException(nameof(destinationType));
this.Logger = logger ?? throw new ArgumentNullException(nameof(logger));
this.SerializerOptions = serializerOptions;
}

}
Expand Down
2 changes: 1 addition & 1 deletion src/EdjCase.JsonRpc.Router/Defaults/DefaultRpcParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ private RpcParameter GetParameter(ref Utf8JsonStreamReader jsonReader)
parameter = RpcParameter.Boolean(jsonReader.GetBoolean());
break;
case JsonTokenType.Null:
parameter = RpcParameter.Null();
parameter = RpcParameter.Null(true);
break;
case JsonTokenType.String:
parameter = RpcParameter.String(jsonReader.GetString());
Expand Down
13 changes: 9 additions & 4 deletions src/EdjCase.JsonRpc.Router/IRpcParameter.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using EdjCase.JsonRpc.Router.Utilities;
using EdjCase.JsonRpc.Router.Utilities;
using System;
using System.Collections.Generic;
using System.ComponentModel;
Expand All @@ -16,8 +16,13 @@ private RpcParameter(RpcParameterType type, object? value)
{
this.Type = type;
this.value = value;
}

public bool GetIfNullIsSpecified()
{
this.ThrowIfNoType(RpcParameterType.Null);
return (bool)this.value!;
}

public bool GetBooleanValue()
{
this.ThrowIfNoType(RpcParameterType.Boolean);
Expand Down Expand Up @@ -69,9 +74,9 @@ public static RpcParameter Boolean(bool value)
return new RpcParameter(RpcParameterType.Boolean, value);
}

public static RpcParameter Null()
public static RpcParameter Null(bool isSpecified)
{
return new RpcParameter(RpcParameterType.Null, null);
return new RpcParameter(RpcParameterType.Null, isSpecified);
}

public static RpcParameter Object(Dictionary<string, RpcParameter> value)
Expand Down
8 changes: 4 additions & 4 deletions test/Benchmarks/Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
Expand Down Expand Up @@ -71,7 +71,7 @@ public void IterationSetup()
[Benchmark]
public void NoParamsNoReturn()
{
this.requestMatcher!.GetMatchingMethod(requestsignature!);
_ = this.requestMatcher!.GetMatchingMethod(this.requestsignature!);
}

[IterationSetup(Target = nameof(ComplexParamNoReturn))]
Expand All @@ -83,7 +83,7 @@ public void ComplexIterationSetup()
[Benchmark]
public void ComplexParamNoReturn()
{
this.requestMatcher!.GetMatchingMethod(requestsignature!);
_ = this.requestMatcher!.GetMatchingMethod(this.requestsignature!);
}


Expand All @@ -102,7 +102,7 @@ public void SimpleIterationSetup()
[Benchmark]
public void SimpleParamsNoReturn()
{
this.requestMatcher!.GetMatchingMethod(requestsignature!);
_ = this.requestMatcher!.GetMatchingMethod(this.requestsignature!);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public bool IsLunchTime()
// https://github.com/edjCase/JsonRpc/issues/99
public IRpcMethodResult CreateInfoHelperItem(string name, string language, string value, string description, string component, string locationIndex, string fontFamily = "Arial", int fontSize = 12, bool bold = false, bool italic = false, bool strikeout = false, bool underline = false)
{
return Ok((name, language, value, description, component, locationIndex, fontFamily, fontSize, bold, italic, strikeout, underline)); ;
return this.Ok((name, language, value, description, component, locationIndex, fontFamily, fontSize, bold, italic, strikeout, underline)); ;
}
}
}
Loading

0 comments on commit 1f559b6

Please sign in to comment.