From fd9e11a18218093d38e504fce74503934acaa9cb Mon Sep 17 00:00:00 2001 From: Harald Wolff Date: Fri, 25 Dec 2020 20:31:19 +0100 Subject: [PATCH] added MapMethodParameters(..) method family to JSONMapper --- ln.json.tests/JSONTests.cs | 50 ++++++++++++++++++++++++++++ ln.json/JSONNumber.cs | 1 + ln.json/JSONObject.cs | 2 ++ ln.json/ln.json.csproj | 2 +- ln.json/mapping/JSONMapper.cs | 61 +++++++++++++++++++++++++++++++++++ 5 files changed, 115 insertions(+), 1 deletion(-) diff --git a/ln.json.tests/JSONTests.cs b/ln.json.tests/JSONTests.cs index c0c5e43..237f6cd 100644 --- a/ln.json.tests/JSONTests.cs +++ b/ln.json.tests/JSONTests.cs @@ -1,4 +1,5 @@ using System; +using System.Reflection; using ln.json.mapping; using NUnit.Framework; @@ -135,6 +136,55 @@ namespace ln.json.tests Assert.AreEqual("C", texts[2]); } + [Test] + public void TestParameterMapping() + { + MethodInfo testMethodInfo = GetType().GetMethod("MappingTestMethod"); + object[] methodArguments = null; + + JSONArray jsonArguments = new JSONArray() + .Add(new JSONString("text parameter value")) + .Add(new JSONNumber(10)) + .Add(new JSONNumber(-2)) + .Add(new JSONNumber(-3)) + ; + + Assert.IsTrue(JSONMapper.DefaultMapper.MapMethodParameters(testMethodInfo, jsonArguments, out object[] arguments)); + Assert.AreEqual("text parameter value", arguments[0]); + Assert.AreEqual(10, arguments[1]); + Assert.AreEqual(-2, arguments[2]); + Assert.AreEqual(-3, arguments[3]); + + jsonArguments.Remove(3); + Assert.IsFalse(JSONMapper.DefaultMapper.MapMethodParameters(testMethodInfo, jsonArguments, out arguments)); + + JSONObject jsonNamedArguments = new JSONObject() + .Add("n", new JSONNumber(10)) + .Add("m", new JSONNumber(-2)) + .Add("a", new JSONNumber(-3)) + .Add("t", new JSONString("text parameter value")) + ; + + Assert.IsTrue(JSONMapper.DefaultMapper.MapMethodParameters(testMethodInfo, jsonNamedArguments, out arguments)); + Assert.AreEqual("text parameter value", arguments[0]); + Assert.AreEqual(10, arguments[1]); + Assert.AreEqual(-2, arguments[2]); + Assert.AreEqual(-3, arguments[3]); + + jsonNamedArguments.Remove("m"); + Assert.IsTrue(JSONMapper.DefaultMapper.MapMethodParameters(testMethodInfo, jsonNamedArguments, out arguments)); + + jsonNamedArguments.Remove("a"); + Assert.IsTrue(JSONMapper.DefaultMapper.MapMethodParameters(testMethodInfo, jsonNamedArguments, out arguments)); + + jsonNamedArguments.Remove("n"); + Assert.IsFalse(JSONMapper.DefaultMapper.MapMethodParameters(testMethodInfo, jsonNamedArguments, out arguments)); + } + + public void MappingTestMethod(string t, int n, short m = 2, long a = 3) + {} + + void TestPrimitiveMapping(object primitiveValue) { Type primitiveType = primitiveValue.GetType(); diff --git a/ln.json/JSONNumber.cs b/ln.json/JSONNumber.cs index d0024e5..f19371f 100644 --- a/ln.json/JSONNumber.cs +++ b/ln.json/JSONNumber.cs @@ -45,6 +45,7 @@ namespace ln.json public JSONNumber(double doubleValue) : base(JSONValueType.NUMBER) { + decValue = doubleValue.ToDecimal(); } public JSONNumber(decimal decValue) diff --git a/ln.json/JSONObject.cs b/ln.json/JSONObject.cs index 4133ed4..dafd85a 100644 --- a/ln.json/JSONObject.cs +++ b/ln.json/JSONObject.cs @@ -40,6 +40,8 @@ namespace ln.json return this; } + public void Remove(string propertyName) => values.Remove(propertyName); + public bool ContainsKey(string key) { return values.ContainsKey(key); diff --git a/ln.json/ln.json.csproj b/ln.json/ln.json.csproj index 22204d8..d952ec0 100644 --- a/ln.json/ln.json.csproj +++ b/ln.json/ln.json.csproj @@ -2,7 +2,7 @@ netcoreapp3.1 - 1.0.6 + 1.0.7 Harald Wolff-Thobaben l--n.de ln.json diff --git a/ln.json/mapping/JSONMapper.cs b/ln.json/mapping/JSONMapper.cs index 0c25a70..f14e1b5 100644 --- a/ln.json/mapping/JSONMapper.cs +++ b/ln.json/mapping/JSONMapper.cs @@ -267,6 +267,67 @@ namespace ln.json.mapping } + + public bool MapMethodParameters(MethodInfo methodInfo, JSONValue jsonArguments, out object[] methodArguments) + { + if (jsonArguments is JSONArray jsonArrayArguments) + return MapMethodParameters(methodInfo.GetParameters(), jsonArrayArguments, out methodArguments); + if (jsonArguments is JSONObject jsonNamedArguments) + return MapMethodParameters(methodInfo.GetParameters(), jsonNamedArguments, out methodArguments); + + throw new ArgumentException(nameof(jsonArguments)); + } + public bool MapMethodParameters(ParameterInfo[] parameterInfos, JSONValue jsonArguments, out object[] methodArguments) + { + if (jsonArguments is JSONArray jsonArrayArguments) + return MapMethodParameters(parameterInfos, jsonArrayArguments, out methodArguments); + if (jsonArguments is JSONObject jsonNamedArguments) + return MapMethodParameters(parameterInfos, jsonNamedArguments, out methodArguments); + + throw new ArgumentException(nameof(jsonArguments)); + } + + public bool MapMethodParameters(MethodInfo methodInfo, JSONObject namedArguments, out object[] methodArguments) => MapMethodParameters(methodInfo.GetParameters(), namedArguments, out methodArguments); + + public bool MapMethodParameters(ParameterInfo[] parameterInfos, JSONObject namedArguments, out object[] methodArguments) + { + methodArguments = new object[parameterInfos.Length]; + + for (int n=0; n < methodArguments.Length; n++) + { + if (namedArguments.ContainsKey(parameterInfos[n].Name)) + { + if (!JSONMapper.DefaultMapper.Deserialize(namedArguments[parameterInfos[n].Name], parameterInfos[n].ParameterType, out methodArguments[n])) + return false; + } else if (parameterInfos[n].IsOptional) + { + methodArguments[n] = parameterInfos[n].DefaultValue; + } else + return false; + } + + return true; + } + + public bool MapMethodParameters(MethodInfo methodInfo, JSONArray jsonArguments, out object[] methodArguments) => MapMethodParameters(methodInfo.GetParameters(), jsonArguments, out methodArguments); + public bool MapMethodParameters(ParameterInfo[] parameterInfos, JSONArray jsonArguments, out object[] methodArguments) + { + methodArguments = new object[parameterInfos.Length]; + + if (jsonArguments.Count != methodArguments.Length) + return false; + + for (int n=0; n < methodArguments.Length; n++) + { + if (!JSONMapper.DefaultMapper.Deserialize(jsonArguments[n], parameterInfos[n].ParameterType, out methodArguments[n])) + return false; + } + + return true; + } + + + static JSONMapper() { DefaultMapper.Add(new JSONMapping(