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

Implement nullable number and boolean support. #5

Merged
merged 1 commit into from
May 30, 2024
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile>

<PackageId>JsonPowerInspector.Template</PackageId>
<PackageVersion>0.0.1</PackageVersion>
<PackageVersion>0.0.2</PackageVersion>
<Authors>DE-YU</Authors>
<Description>Provides necessary data models and serializers for developers to collect and create serialization info for their data types to use with JsonPowerInspector.</Description>
<PackageProjectUrl>https://www.nuget.org/packages/JsonPowerInspector.Template</PackageProjectUrl>
<PackageReadmeFile>README.md</PackageReadmeFile>
<RepositoryUrl>https://github.com/Delsin-Yu/Json-Power-Inspector</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>Json Inspector</PackageTags>
<PackageReleaseNotes>The initial release of the JsonPowerInspector.Template nuget package.</PackageReleaseNotes>
<PackageReleaseNotes>Add support for nullable number and boolean values.</PackageReleaseNotes>
<PackageLicenseExpression>MIT</PackageLicenseExpression>

<IncludeSymbols>true</IncludeSymbols>
Expand Down
19 changes: 17 additions & 2 deletions JsonPowerInspector.Template/Models.cs
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,18 @@ internal StringPropertyInfo(string name, string displayName) : base(name, displa
/// </summary>
public class BooleanPropertyInfo : BaseObjectPropertyInfo
{
/// <summary>
/// Is this property nullable.
/// </summary>
public bool Nullable { get; }

private protected override void PrintType(StringBuilder stringBuilder) => stringBuilder.Append("Bool");

[JsonConstructor]
internal BooleanPropertyInfo(string name, string displayName) : base(name, displayName) { }
internal BooleanPropertyInfo(string name, string displayName, bool nullable) : base(name, displayName)
{
Nullable = nullable;
}
}

/// <summary>
Expand Down Expand Up @@ -228,11 +237,17 @@ public enum NumberType
/// </summary>
public NumberRange? Range { get; }

/// <summary>
/// Is this property nullable.
/// </summary>
public bool Nullable { get; }

[JsonConstructor]
internal NumberPropertyInfo(string name, string displayName, NumberType numberKind, NumberRange? range = null) : base(name, displayName)
internal NumberPropertyInfo(string name, string displayName, bool nullable, NumberType numberKind, NumberRange? range = null) : base(name, displayName)
{
NumberKind = numberKind;
Range = range;
Nullable = nullable;
}

private protected override void PrintType(StringBuilder stringBuilder)
Expand Down
30 changes: 30 additions & 0 deletions JsonPowerInspector.Template/TemplateSerializer.Array.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;

namespace JsonPowerInspector.Template;

public static partial class TemplateSerializer
{
private static bool SerializeArrayProperty(string name, Type propertyType,
Dictionary<string, ObjectDefinition> referencedPropertyInfo,
[NotNullWhen(true)] ref BaseObjectPropertyInfo? baseObjectPropertyInfo,
Attribute[] attributesArray,
string displayName)
{
var elementType = propertyType.GetElementType()!;
if (!TryParseProperty(
GetTypeName(elementType),
elementType,
referencedPropertyInfo,
attributesArray,
out var arrayElementTypeInfo
))
{
return false;
}

baseObjectPropertyInfo = new ArrayPropertyInfo(name, displayName, arrayElementTypeInfo);
return true;
}
}
35 changes: 35 additions & 0 deletions JsonPowerInspector.Template/TemplateSerializer.Enum.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace JsonPowerInspector.Template;

public static partial class TemplateSerializer
{
private static void SerializeEnumProperty(string name, Type propertyType,
out BaseObjectPropertyInfo baseObjectPropertyInfo, string displayName)
{
var enumValuesList = new List<EnumPropertyInfo.EnumValue>();

foreach (var enumField in propertyType.GetFields(BindingFlags.Static | BindingFlags.Public))
{
var inspectorNameAttribute = enumField.GetCustomAttribute<InspectorNameAttribute>();
enumValuesList.Add(
new(
inspectorNameAttribute?.DisplayName ?? enumField.Name,
enumField.Name,
Convert.ToInt64(enumField.GetRawConstantValue())
)
);
}

baseObjectPropertyInfo = new EnumPropertyInfo(
name,
displayName,
propertyType.Name,
enumValuesList.ToArray(),
propertyType.GetCustomAttributes<FlagsAttribute>().Any()
);
}
}
95 changes: 95 additions & 0 deletions JsonPowerInspector.Template/TemplateSerializer.Generic.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;

namespace JsonPowerInspector.Template;

public static partial class TemplateSerializer
{
private static bool SerializeGenericProperty(string name, Type propertyType,
Dictionary<string, ObjectDefinition> referencedPropertyInfo,
[NotNullWhen(true)] ref BaseObjectPropertyInfo? baseObjectPropertyInfo,
Attribute[] attributesArray, string displayName)
{
var genericTypeDef = propertyType.GetGenericTypeDefinition();
if (genericTypeDef == typeof(List<>))
{
var elementType = propertyType.GetGenericArguments()[0];
if (!TryParseProperty(
GetTypeName(elementType),
elementType,
referencedPropertyInfo,
attributesArray,
out var arrayElementTypeInfo
))
{
return false;
}

baseObjectPropertyInfo = new ArrayPropertyInfo(name, displayName, arrayElementTypeInfo);
}
else if (genericTypeDef == typeof(Dictionary<,>))
{
var arguments = propertyType.GetGenericArguments();
var keyType = arguments[0];
var valueType = arguments[1];
var attributeArray = attributesArray.ToArray();

var attributesList = new List<Attribute>(2);

var keyDropdown = (DropdownAttribute?)attributeArray.OfType<KeyDropdownAttribute>().FirstOrDefault();
var keyNumberRange =
(NumberRangeAttribute?)attributeArray.OfType<KeyNumberRangeAttribute>().FirstOrDefault();

if (keyDropdown != null) attributesList.Add(keyDropdown);
if (keyNumberRange != null) attributesList.Add(keyNumberRange);

if (!TryParseProperty(
GetTypeName(keyType),
keyType,
referencedPropertyInfo,
attributesList,
out var keyTypeInfo
))
{
return false;
}

attributesList.Clear();

var valueDropdown = (DropdownAttribute?)attributeArray.OfType<ValueDropdownAttribute>().FirstOrDefault();
var valueNumberRange =
(NumberRangeAttribute?)attributeArray.OfType<ValueNumberRangeAttribute>().FirstOrDefault();

if (valueDropdown != null) attributesList.Add(valueDropdown);
if (valueNumberRange != null) attributesList.Add(valueNumberRange);

if (!TryParseProperty(
GetTypeName(valueType),
valueType,
referencedPropertyInfo,
attributesList,
out var valueTypeInfo
))
{
referencedPropertyInfo.Remove(GetTypeName(keyType));
return false;
}

baseObjectPropertyInfo = new DictionaryPropertyInfo(name, displayName, keyTypeInfo, valueTypeInfo);
}
else if (genericTypeDef == typeof(Nullable<>))
{
var arguments = propertyType.GetGenericArguments();
if (!SerializePrimitiveProperty(name, arguments[0], ref baseObjectPropertyInfo, displayName,
attributesArray, true)) return false;
}
else
{
return false;
}

return true;
}
}
24 changes: 24 additions & 0 deletions JsonPowerInspector.Template/TemplateSerializer.Object.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;

namespace JsonPowerInspector.Template;

public static partial class TemplateSerializer
{
private static void SerializeObjectProperty(string name, Type propertyType,
Dictionary<string, ObjectDefinition> referencedPropertyInfo,
out BaseObjectPropertyInfo baseObjectPropertyInfo, string displayName)
{
EnsureTypeExists(propertyType);
baseObjectPropertyInfo = new ObjectPropertyInfo(name, displayName, GetTypeName(propertyType));

void EnsureTypeExists(Type type)
{
if (type.IsPrimitive || type == typeof(string) || type.IsEnum) return;
var typeName = GetTypeName(type);
if (!referencedPropertyInfo.TryAdd(typeName, TempObjectProperty)) return;
var typeDefinition = CollectTypeDefinitionImpl(type, referencedPropertyInfo);
referencedPropertyInfo[typeName] = typeDefinition;
}
}
}
64 changes: 64 additions & 0 deletions JsonPowerInspector.Template/TemplateSerializer.Primitive.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;

namespace JsonPowerInspector.Template;

public static partial class TemplateSerializer
{
private static bool SerializePrimitiveProperty(string name, Type propertyType,
[NotNullWhen(true)] ref BaseObjectPropertyInfo? baseObjectPropertyInfo, string displayName,
Attribute[] attributesArray, bool nullable)
{
if (propertyType == typeof(bool))
{
baseObjectPropertyInfo = new BooleanPropertyInfo(name, displayName, nullable);
}
else
{
NumberPropertyInfo.NumberType numberType;

if (propertyType == typeof(byte)) numberType = NumberPropertyInfo.NumberType.Int;
else if (propertyType == typeof(ushort)) numberType = NumberPropertyInfo.NumberType.Int;
else if (propertyType == typeof(uint)) numberType = NumberPropertyInfo.NumberType.Int;
else if (propertyType == typeof(ulong)) numberType = NumberPropertyInfo.NumberType.Int;
else if (propertyType == typeof(sbyte)) numberType = NumberPropertyInfo.NumberType.Int;
else if (propertyType == typeof(short)) numberType = NumberPropertyInfo.NumberType.Int;
else if (propertyType == typeof(int)) numberType = NumberPropertyInfo.NumberType.Int;
else if (propertyType == typeof(long)) numberType = NumberPropertyInfo.NumberType.Int;
else if (propertyType == typeof(float)) numberType = NumberPropertyInfo.NumberType.Float;
else if (propertyType == typeof(double)) numberType = NumberPropertyInfo.NumberType.Float;
else return false;

var dropdown = attributesArray.OfType<DropdownAttribute>().FirstOrDefault();
if (dropdown != null)
{
baseObjectPropertyInfo = new DropdownPropertyInfo(
name,
displayName,
numberType switch
{
NumberPropertyInfo.NumberType.Int => DropdownPropertyInfo.DropdownKind.Int,
NumberPropertyInfo.NumberType.Float => DropdownPropertyInfo.DropdownKind.Float,
_ => throw new InvalidOperationException()
},
dropdown.DataPath,
dropdown.Regex
);
}
else
{
NumberPropertyInfo.NumberRange? range = null;
var numberRange = attributesArray.OfType<NumberRangeAttribute>().FirstOrDefault();
if (numberRange != null)
{
range = new(numberRange.LowerBound, numberRange.UpperBound);
}

baseObjectPropertyInfo = new NumberPropertyInfo(name, displayName, nullable, numberType, range);
}
}

return true;
}
}
27 changes: 27 additions & 0 deletions JsonPowerInspector.Template/TemplateSerializer.String.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System;
using System.Linq;

namespace JsonPowerInspector.Template;

public static partial class TemplateSerializer
{
private static void SerializeStringProperty(string name, out BaseObjectPropertyInfo baseObjectPropertyInfo,
Attribute[] attributesArray, string displayName)
{
var dropdown = attributesArray.OfType<DropdownAttribute>().FirstOrDefault();
if (dropdown != null)
{
baseObjectPropertyInfo = new DropdownPropertyInfo(
name,
displayName,
DropdownPropertyInfo.DropdownKind.String,
dropdown.DataPath,
dropdown.Regex
);
}
else
{
baseObjectPropertyInfo = new StringPropertyInfo(name, displayName);
}
}
}
Loading