Compare commits
18 Commits
Author | SHA1 | Date |
---|---|---|
Harald Wolff | fa6b73cccd | |
Harald Wolff | cf3952a9ba | |
Harald Wolff | fb6d4fdede | |
Harald Wolff | e8cd08cb4c | |
Harald Wolff | 12d75bbc64 | |
Harald Wolff | abd6a15bfa | |
Harald Wolff | f1aca689be | |
Harald Wolff | ccd0a507bc | |
Harald Wolff | 3677c6847b | |
Harald Wolff | 3e2e2d717c | |
Harald Wolff | fdef5cc1a7 | |
Harald Wolff | 04531d4382 | |
Harald Wolff | 8d397ecbc6 | |
Harald Wolff | fd9e11a182 | |
Harald Wolff | 02adec8cb8 | |
Harald Wolff | 492e232fa7 | |
Harald Wolff | a6757e1b63 | |
Harald Wolff | 2b807bcb73 |
|
@ -0,0 +1,13 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Rider ignored files
|
||||
/.idea.ln.json.iml
|
||||
/modules.xml
|
||||
/projectSettingsUpdater.xml
|
||||
/contentModel.xml
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
|
||||
</project>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="UserContentModel">
|
||||
<attachedFolders />
|
||||
<explicitIncludes />
|
||||
<explicitExcludes />
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
2
build.ln
2
build.ln
|
@ -3,7 +3,7 @@
|
|||
"dotnet"
|
||||
],
|
||||
"env": {
|
||||
"NUGET_SOURCE": "https://nexus.niclas-thobaben.de/repository/l--n.de/",
|
||||
"NUGET_SOURCE": "https://nexus.l--n.de/repository/ln.net/",
|
||||
"CONFIGURATION": "Release"
|
||||
},
|
||||
"stages": [
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
using ln.json.mapping;
|
||||
using NUnit.Framework;
|
||||
|
||||
|
@ -87,6 +88,7 @@ namespace ln.json.tests
|
|||
TestEnumSerialization(testEnum3.C);
|
||||
TestEnumSerialization(testEnum3.D);
|
||||
TestEnumSerialization(testEnum3.E);
|
||||
TestEnumSerialization((testEnum3)23);
|
||||
}
|
||||
|
||||
bool TestEnumSerialization(object enumValue)
|
||||
|
@ -125,6 +127,65 @@ namespace ln.json.tests
|
|||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDeserialize()
|
||||
{
|
||||
Assert.IsTrue(JSONMapper.DefaultMapper.Deserialize("[\"A\",\"B\",\"C\"]", out string[] texts));
|
||||
Assert.AreEqual(3, texts.Length);
|
||||
Assert.AreEqual("A", texts[0]);
|
||||
Assert.AreEqual("B", texts[1]);
|
||||
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();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
@ -9,7 +9,7 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="3.16.1" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0"/>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -32,14 +32,35 @@ namespace ln.json
|
|||
public JSONArray()
|
||||
: base(JSONValueType.ARRAY) { }
|
||||
|
||||
public JSONArray(IEnumerable<JSONValue> values)
|
||||
: base(JSONValueType.ARRAY)
|
||||
{
|
||||
this.values.AddRange(values);
|
||||
}
|
||||
|
||||
public static JSONArray From<T>(IEnumerable<T> values) where T:JSONValue
|
||||
{
|
||||
return new JSONArray(values);
|
||||
}
|
||||
|
||||
|
||||
public override JSONValue this[int index] {
|
||||
get => values[index];
|
||||
set => values[index] = value;
|
||||
}
|
||||
|
||||
public JSONArray Add(IEnumerable<JSONValue> values){ foreach (JSONValue value in values) this.values.Add(value); return this; }
|
||||
public JSONArray Add(JSONValue value){ values.Add(value); return this; }
|
||||
public JSONArray Remove(int index) { values.RemoveAt(index); return this; }
|
||||
|
||||
public override JSONValue Clone()
|
||||
{
|
||||
JSONArray copy = new JSONArray();
|
||||
foreach (var value in values)
|
||||
copy.Add(value.Clone());
|
||||
return copy;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
|
||||
|
@ -61,5 +82,14 @@ namespace ln.json
|
|||
return sb.ToString();
|
||||
}
|
||||
|
||||
public IEnumerable<OT> GetValues<OT>()
|
||||
{
|
||||
foreach (var value in values)
|
||||
{
|
||||
if (value is OT otValue)
|
||||
yield return otValue;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,10 @@ namespace ln.json
|
|||
return (double)decValue;
|
||||
}
|
||||
|
||||
public JSONNumber(byte i)
|
||||
: this((long)i) { }
|
||||
public JSONNumber(sbyte i)
|
||||
: this((long)i) { }
|
||||
public JSONNumber(short i)
|
||||
: this((long)i) { }
|
||||
public JSONNumber(ushort i)
|
||||
|
@ -45,6 +49,7 @@ namespace ln.json
|
|||
public JSONNumber(double doubleValue)
|
||||
: base(JSONValueType.NUMBER)
|
||||
{
|
||||
|
||||
decValue = doubleValue.ToDecimal();
|
||||
}
|
||||
public JSONNumber(decimal decValue)
|
||||
|
@ -52,10 +57,21 @@ namespace ln.json
|
|||
{
|
||||
this.decValue = decValue;
|
||||
}
|
||||
|
||||
public override JSONValue Clone() => new JSONNumber(this.decValue);
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return decValue.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
|
||||
public static implicit operator Decimal(JSONNumber j) => j.decValue;
|
||||
public static implicit operator float(JSONNumber j) => (float)j.decValue;
|
||||
public static implicit operator double(JSONNumber j) => (double)j.decValue;
|
||||
public static implicit operator int(JSONNumber j) => (int)j.decValue;
|
||||
public static implicit operator long(JSONNumber j) => (long)j.decValue;
|
||||
public static implicit operator uint(JSONNumber j) => (uint)j.decValue;
|
||||
public static implicit operator ulong(JSONNumber j) => (ulong)j.decValue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using System.Dynamic;
|
||||
using ln.collections;
|
||||
using ln.json.mapping;
|
||||
|
||||
|
@ -40,11 +41,27 @@ namespace ln.json
|
|||
return this;
|
||||
}
|
||||
|
||||
public void Remove(string propertyName) => values.Remove(propertyName);
|
||||
|
||||
public bool ContainsKey(string key)
|
||||
{
|
||||
return values.ContainsKey(key);
|
||||
}
|
||||
|
||||
public bool TryGetValue(string key, out JSONValue jsonValue) => values.TryGet(key, out jsonValue);
|
||||
|
||||
public bool TryGetValue<OT>(string key, out OT value) where OT : JSONValue
|
||||
{
|
||||
if (TryGetValue(key, out JSONValue jsonValue) && (jsonValue is OT otValue))
|
||||
{
|
||||
value = otValue;
|
||||
return true;
|
||||
}
|
||||
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
public T ToObject<T>()
|
||||
{
|
||||
if (JSONMapper.DefaultMapper.Deserialize(this, typeof(T), out object o))
|
||||
|
@ -54,6 +71,14 @@ namespace ln.json
|
|||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override JSONValue Clone()
|
||||
{
|
||||
JSONObject copy = new JSONObject();
|
||||
foreach (var key in Keys)
|
||||
copy[key] = this[key].Clone();
|
||||
return copy;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
@ -78,6 +103,28 @@ namespace ln.json
|
|||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override bool TryGetMember(GetMemberBinder binder, out object? result)
|
||||
{
|
||||
if (values.TryGet(binder.Name, out JSONValue jsonValue))
|
||||
{
|
||||
result = jsonValue;
|
||||
return true;
|
||||
}
|
||||
result = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool TrySetMember(SetMemberBinder binder, object? value)
|
||||
{
|
||||
if (value is JSONValue jsonValue)
|
||||
values[binder.Name] = jsonValue;
|
||||
else
|
||||
values[binder.Name] = JSONMapper.DefaultMapper.ToJson(value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static JSONObject From(object value)
|
||||
{
|
||||
if (JSONMapper.DefaultMapper.Serialize(value, out JSONValue json))
|
||||
|
|
|
@ -5,6 +5,8 @@ namespace ln.json
|
|||
{
|
||||
public static JSONTrue Instance { get; } = new JSONTrue();
|
||||
private JSONTrue() : base(JSONValueType.TRUE) { }
|
||||
public override JSONValue Clone() => this;
|
||||
|
||||
public override string ToString() => "true";
|
||||
public override object ToNative() => true;
|
||||
}
|
||||
|
@ -12,6 +14,8 @@ namespace ln.json
|
|||
{
|
||||
public static JSONFalse Instance { get; } = new JSONFalse();
|
||||
private JSONFalse() : base(JSONValueType.FALSE) { }
|
||||
public override JSONValue Clone() => this;
|
||||
|
||||
public override string ToString() => "false";
|
||||
public override object ToNative() => false;
|
||||
}
|
||||
|
@ -19,6 +23,8 @@ namespace ln.json
|
|||
{
|
||||
public static JSONNull Instance { get; } = new JSONNull();
|
||||
private JSONNull() : base(JSONValueType.NULL) { }
|
||||
public override JSONValue Clone() => this;
|
||||
|
||||
public override string ToString() => "null";
|
||||
public override object ToNative() => null;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@ namespace ln.json
|
|||
Value = value;
|
||||
}
|
||||
|
||||
public override JSONValue Clone() => new JSONString(Value);
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("\"{0}\"", Escape(Value));
|
||||
|
@ -95,5 +97,7 @@ namespace ln.json
|
|||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static implicit operator String(JSONString j) => j.Value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,13 +9,19 @@
|
|||
// **/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Dynamic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using ln.type;
|
||||
|
||||
namespace ln.json
|
||||
{
|
||||
public enum JSONValueType
|
||||
{
|
||||
NULL, OBJECT, ARRAY, STRING, NUMBER, TRUE, FALSE
|
||||
}
|
||||
public abstract class JSONValue
|
||||
public abstract class JSONValue : DynamicObject
|
||||
{
|
||||
public JSONValueType ValueType { get; private set; }
|
||||
|
||||
|
@ -24,6 +30,8 @@ namespace ln.json
|
|||
|
||||
public virtual object ToNative() => throw new NotImplementedException();
|
||||
|
||||
public T As<T>() where T : JSONValue => this as T;
|
||||
|
||||
public JSONValue(JSONValueType valueType)
|
||||
{
|
||||
ValueType = valueType;
|
||||
|
@ -40,6 +48,30 @@ namespace ln.json
|
|||
set => throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public abstract JSONValue Clone();
|
||||
|
||||
public override string ToString() => throw new NotImplementedException();
|
||||
|
||||
public virtual void WriteTo(string filename)
|
||||
{
|
||||
using (var fs = new FileStream(filename, FileMode.Create, FileAccess.Write))
|
||||
{
|
||||
WriteTo(fs);
|
||||
}
|
||||
}
|
||||
public virtual void WriteTo(Stream stream)
|
||||
{
|
||||
stream.Write(Encoding.UTF8.GetBytes(this.ToString()!));
|
||||
}
|
||||
|
||||
public static implicit operator JSONValue(string v) => new JSONString(v);
|
||||
public static implicit operator JSONValue(float v) => new JSONNumber(v);
|
||||
public static implicit operator JSONValue(double v) => new JSONNumber(v);
|
||||
public static implicit operator JSONValue(decimal v) => new JSONNumber(v);
|
||||
public static implicit operator JSONValue(int v) => new JSONNumber(v);
|
||||
public static implicit operator JSONValue(long v) => new JSONNumber(v);
|
||||
public static implicit operator JSONValue(uint v) => new JSONNumber(v);
|
||||
public static implicit operator JSONValue(ulong v) => new JSONNumber(v);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
using System;
|
||||
|
||||
namespace ln.json.attributes;
|
||||
|
||||
public class DontAssign : Attribute
|
||||
{
|
||||
}
|
|
@ -1,8 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<Version>1.0.3</Version>
|
||||
<Version>1.0.8-ci</Version>
|
||||
<Authors>Harald Wolff-Thobaben</Authors>
|
||||
<Company>l--n.de</Company>
|
||||
<Product>ln.json</Product>
|
||||
|
@ -10,11 +9,13 @@
|
|||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<AssemblyVersion>0.1.0.0</AssemblyVersion>
|
||||
<FileVersion>0.1.0.0</FileVersion>
|
||||
<PackageVersion>1.3.0-preview8</PackageVersion>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Runtime" Version="4.3.1" />
|
||||
<PackageReference Include="ln.type" Version="0.1.3" />
|
||||
<PackageReference Include="ln.collections" Version="0.1.2" />
|
||||
<PackageReference Include="ln.type" Version="0.1.9" />
|
||||
<PackageReference Include="ln.collections" Version="0.2.2" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
|
||||
namespace ln.json.mapping
|
||||
|
@ -54,21 +55,38 @@ namespace ln.json.mapping
|
|||
|
||||
|
||||
Dictionary<Type, JSONMapping> mappings = new Dictionary<Type, JSONMapping>();
|
||||
public virtual void Add(JSONMapping mapping) => mappings[mapping.TargetType] = mapping;
|
||||
|
||||
public virtual void Add(JSONMapping mapping)
|
||||
{
|
||||
lock (mappings)
|
||||
{
|
||||
mappings[mapping.TargetType] = mapping;
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary<Type, MappingFactory> mappingFactories = new Dictionary<Type, MappingFactory>();
|
||||
public virtual void AddMappingFactory(Type targetType, MappingFactory mappingFactory) => mappingFactories.Add(targetType, mappingFactory);
|
||||
|
||||
public virtual bool GetOrBuildMapping(Type nativeType, out JSONMapping mapping) => TryGetMapping(nativeType, out mapping) || TryBuildRememberedMapping(nativeType, out mapping);
|
||||
public virtual bool GetOrBuildMapping(Type nativeType, out JSONMapping mapping)
|
||||
{
|
||||
lock (mappings)
|
||||
{
|
||||
return TryGetMapping(nativeType, out mapping) || TryBuildRememberedMapping(nativeType, out mapping);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool TryBuildRememberedMapping(Type nativeType,out JSONMapping mapping)
|
||||
{
|
||||
if (TryBuildMapping(nativeType, out mapping))
|
||||
lock (mappings)
|
||||
{
|
||||
mappings.Add(nativeType, mapping);
|
||||
return true;
|
||||
if (TryBuildMapping(nativeType, out mapping))
|
||||
{
|
||||
mappings.Add(nativeType, mapping);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public virtual bool TryBuildMapping(Type nativeType,out JSONMapping mapping)
|
||||
{
|
||||
|
@ -119,73 +137,107 @@ namespace ln.json.mapping
|
|||
|
||||
public virtual bool TryGetMapping(Type nativeType,out JSONMapping mapping)
|
||||
{
|
||||
if (mappings.TryGetValue(nativeType, out mapping))
|
||||
return true;
|
||||
lock (mappings)
|
||||
{
|
||||
if (mappings.TryGetValue(nativeType, out mapping))
|
||||
return true;
|
||||
|
||||
if (RequestCustomMapping(nativeType, out mapping))
|
||||
return true;
|
||||
if (RequestCustomMapping(nativeType, out mapping))
|
||||
return true;
|
||||
|
||||
if ((this != DefaultMapper) && DefaultMapper.TryGetMapping(nativeType, out mapping))
|
||||
return true;
|
||||
if ((this != DefaultMapper) && DefaultMapper.TryGetMapping(nativeType, out mapping))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public virtual bool Serialize(object o, out JSONValue json)
|
||||
{
|
||||
if (object.ReferenceEquals(null, o))
|
||||
if (o is JSONValue jValue)
|
||||
{
|
||||
json = JSONNull.Instance;
|
||||
json = jValue.Clone();
|
||||
return true;
|
||||
}
|
||||
|
||||
Type type = o.GetType();
|
||||
|
||||
if (RequestCustomSerialization(o, out json))
|
||||
return true;
|
||||
|
||||
if (TryGetMapping(type, out JSONMapping mapping))
|
||||
lock (mappings)
|
||||
{
|
||||
json = mapping.ToJson(this, o);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (type.IsEnum)
|
||||
{
|
||||
if (type.GetCustomAttribute<FlagsAttribute>() != null)
|
||||
if (object.ReferenceEquals(null, o))
|
||||
{
|
||||
Type enumBaseType = type.GetEnumUnderlyingType();
|
||||
o = Convert.ChangeType(o, enumBaseType);
|
||||
ConstructorInfo constructor = typeof(JSONNumber).GetConstructor(new Type[]{ enumBaseType });
|
||||
json = (JSONNumber)constructor.Invoke(new object[]{ o });
|
||||
json = JSONNull.Instance;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
||||
Type type = o.GetType();
|
||||
|
||||
if (RequestCustomSerialization(o, out json))
|
||||
return true;
|
||||
|
||||
if (TryGetMapping(type, out JSONMapping mapping))
|
||||
{
|
||||
json = new JSONString(Enum.GetName(type, o));
|
||||
json = mapping.ToJson(this, o);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (type.IsEnum)
|
||||
{
|
||||
if (type.GetCustomAttribute<FlagsAttribute>() != null)
|
||||
{
|
||||
Type enumBaseType = type.GetEnumUnderlyingType();
|
||||
o = Convert.ChangeType(o, enumBaseType);
|
||||
ConstructorInfo constructor = typeof(JSONNumber).GetConstructor(new Type[] { enumBaseType });
|
||||
json = (JSONNumber)constructor.Invoke(new object[] { o });
|
||||
}
|
||||
else
|
||||
{
|
||||
json = new JSONString(Enum.GetName(type, o));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (type.IsPrimitive)
|
||||
{
|
||||
throw new NotSupportedException(
|
||||
String.Format("JSONMapperBase: Unsupported primitive type found: {0}", type));
|
||||
}
|
||||
|
||||
if (TryBuildRememberedMapping(type, out mapping))
|
||||
{
|
||||
json = mapping.ToJson(this, o);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool Deserialize<T>(string jsonSource, out T v) => Deserialize(JSONParser.Parse(jsonSource), out v);
|
||||
public virtual bool Deserialize<T>(JSONValue json, out T v)
|
||||
{
|
||||
if (Deserialize(json, typeof(T), out object o))
|
||||
{
|
||||
v = (T)o;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (type.IsPrimitive)
|
||||
{
|
||||
throw new NotSupportedException(String.Format("JSONMapperBase: Unsupported primitive type found: {0}", type));
|
||||
}
|
||||
|
||||
if (TryBuildRememberedMapping(type,out mapping))
|
||||
{
|
||||
json = mapping.ToJson(this, o);
|
||||
return true;
|
||||
}
|
||||
|
||||
v = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual bool Deserialize(string jsonSource, Type nativeType, out object o) => Deserialize(JSONParser.Parse(jsonSource), nativeType, out o);
|
||||
public virtual bool Deserialize(JSONValue json, Type nativeType, out object o)
|
||||
{
|
||||
o = null;
|
||||
|
||||
if (nativeType.IsSubclassOf(typeof(JSONValue)))
|
||||
{
|
||||
o = json.Clone();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
if (JSONNull.Instance.Equals(json))
|
||||
return true;
|
||||
|
||||
|
@ -254,6 +306,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(
|
||||
|
@ -261,6 +374,11 @@ namespace ln.json.mapping
|
|||
(JSONMapper arg1, object arg2) => new JSONNumber((int)(byte)arg2),
|
||||
(JSONMapper arg1, JSONValue arg2) => Decimal.ToByte(((JSONNumber)arg2).Decimal)
|
||||
));
|
||||
DefaultMapper.Add(new JSONMapping(
|
||||
typeof(sbyte),
|
||||
(JSONMapper arg1, object arg2) => new JSONNumber((int)(sbyte)arg2),
|
||||
(JSONMapper arg1, JSONValue arg2) => Decimal.ToSByte(((JSONNumber)arg2).Decimal)
|
||||
));
|
||||
DefaultMapper.Add(new JSONMapping(
|
||||
typeof(short),
|
||||
(JSONMapper arg1, object arg2) => new JSONNumber((int)(short)arg2),
|
||||
|
@ -329,7 +447,7 @@ namespace ln.json.mapping
|
|||
DefaultMapper.Add(new JSONMapping(
|
||||
typeof(bool),
|
||||
(JSONMapper arg1, object arg2) => ((bool)arg2) ? (JSONValue)JSONTrue.Instance : (JSONValue)JSONFalse.Instance,
|
||||
(JSONMapper arg1, JSONValue arg2) => (arg2.ValueType == JSONValueType.TRUE) || (arg2.ValueType == JSONValueType.FALSE) ? false : throw new NotSupportedException()
|
||||
(JSONMapper arg1, JSONValue arg2) => (arg2.ValueType == JSONValueType.TRUE) ? true : false
|
||||
));
|
||||
|
||||
DefaultMapper.Add(new JSONByteArrayMapping());
|
||||
|
@ -343,6 +461,12 @@ namespace ln.json.mapping
|
|||
|
||||
DefaultMapper.Add(new JSONRPCCallMapping());
|
||||
DefaultMapper.Add(new JSONRPCResultMapping());
|
||||
|
||||
DefaultMapper.Add(new JSONMapping(
|
||||
typeof(IPAddress),
|
||||
((mapper, o) => ((IPAddress)o).ToString()),
|
||||
(mapper, value) => IPAddress.Parse((value as JSONString).Value))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ namespace ln.json.mapping
|
|||
Dictionary<string, Action<object,object>> setters = new Dictionary<string, Action<object,object>>();
|
||||
Dictionary<string, Func<object, object>> getters = new Dictionary<string, Func<object, object>>();
|
||||
Dictionary<string, Type> types = new Dictionary<string, Type>();
|
||||
private HashSet<string> _dontAssign = new HashSet<string>();
|
||||
|
||||
public JSONObjectMapping(Type type)
|
||||
: this(type, JSONObjectMappingFlags.FIELDS | JSONObjectMappingFlags.PROPERTIES, BindingFlags.Instance | BindingFlags.Public)
|
||||
|
@ -44,6 +45,8 @@ namespace ln.json.mapping
|
|||
setters.Add(fieldInfo.Name, (object arg1, object arg2) => fieldInfo.SetValue(arg1, arg2));
|
||||
getters.Add(fieldInfo.Name, (object arg) => fieldInfo.GetValue(arg));
|
||||
types.Add(fieldInfo.Name, fieldInfo.FieldType);
|
||||
if (fieldInfo.GetCustomAttribute<DontAssign>() != null)
|
||||
_dontAssign.Add(fieldInfo.Name);
|
||||
}
|
||||
}
|
||||
if ((mappingFlags & JSONObjectMappingFlags.PROPERTIES) == JSONObjectMappingFlags.PROPERTIES)
|
||||
|
@ -55,6 +58,8 @@ namespace ln.json.mapping
|
|||
setters.Add(propertyInfo.Name, (object arg1, object arg2) => { if (propertyInfo.CanWrite) propertyInfo.SetValue(arg1, arg2); });
|
||||
getters.Add(propertyInfo.Name, (object arg) => propertyInfo.GetValue(arg));
|
||||
types.Add(propertyInfo.Name, propertyInfo.PropertyType);
|
||||
if (propertyInfo.GetCustomAttribute<DontAssign>() != null)
|
||||
_dontAssign.Add(propertyInfo.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -102,5 +107,20 @@ namespace ln.json.mapping
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool Assign(JSONMapper mapper, object o, JSONObject json)
|
||||
{
|
||||
bool applied = false;
|
||||
foreach (string name in setters.Keys)
|
||||
{
|
||||
if (json.ContainsKey(name) && !_dontAssign.Contains(name))
|
||||
{
|
||||
setters[name](o, mapper.FromJson(json[name], types[name]));
|
||||
applied = true;
|
||||
}
|
||||
}
|
||||
|
||||
return applied;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue