Skip to content

Commit

Permalink
mappers
Browse files Browse the repository at this point in the history
  • Loading branch information
CypherPotato committed Nov 23, 2023
1 parent 39b0195 commit 9f07a8f
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 87 deletions.
3 changes: 3 additions & 0 deletions Sources/LightJson/JsonOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,7 @@ public static class JsonOptions
/// Gets or sets whether the JSON serializer should throw an exception when trying to convert a value to an invalid type.
/// </summary>
public static bool ThrowOnInvalidCast { get; set; } = false;

public static HashSet<JsonSerializerMapper> Mappers { get; set; } = new HashSet<JsonSerializerMapper>();

}
13 changes: 13 additions & 0 deletions Sources/LightJson/JsonSerializerMapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace LightJson;

public abstract class JsonSerializerMapper
{
public abstract bool CanSerialize(object obj);
public abstract bool CanDeserialize(JsonValue value);
public abstract JsonValue Serialize(object value);
public abstract object Deserialize(JsonValue value);
}
182 changes: 97 additions & 85 deletions Sources/LightJson/JsonValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,15 +120,89 @@ public bool IsJsonArray
}
}

/// <summary>
/// Gets a value indicating whether this JsonValue represents a DateTime.
/// </summary>
public bool IsDateTime
public T? As<T>()
{
get
if (Is<T>(out T? output))
{
return output;
} else
{
return ThrowOrNull<T>();
}
}

public bool Is<T>(out T? output)
{
Type tType = typeof(T);

if (IsNull)
{
output = default;
return false;
}

if (tType == typeof(bool))
{
if (IsBoolean)
{
output = (T)(object)(this.value == 1 ? true : false);
return true;
}
else
{
output = default;
return false;
}
}
if (tType == typeof(string))
{
if (IsString)
{
output = (T)this.reference;
return true;
}
else
{
output = default;
return false;
}
}
else if (tType == typeof(int)
|| tType == typeof(byte)
|| tType == typeof(short)
|| tType == typeof(ushort)
|| tType == typeof(uint)
|| tType == typeof(sbyte)
|| tType == typeof(long)
|| tType == typeof(ulong)
|| tType == typeof(decimal)
|| tType == typeof(double)
|| tType == typeof(float))
{
if (IsNumber)
{
output = (T)(object)this.value;
return true;
}
else
{
output = default;
return false;
}
}

foreach (var mapper in JsonOptions.Mappers)
{
return this.AsDateTime != default;
if (mapper.CanDeserialize(this))
{
object result = mapper.Deserialize(this);
output = (T)result;
return true;
}
}

output = default;
return false;
}

/// <summary>
Expand Down Expand Up @@ -172,14 +246,13 @@ public int AsInteger
{
var value = this.AsNumber;

// Prevent overflow if the value doesn't fit.
if (value >= int.MaxValue)
{
return int.MaxValue;
throw new OverflowException("The value in the JSON content is too big or too small for an Int32.");
}
if (value <= int.MinValue)
{
return int.MinValue;
throw new OverflowException("The value in the JSON content is too big or too small for an Int32.");
}

return (int)value;
Expand Down Expand Up @@ -240,6 +313,9 @@ public string? AsString
case JsonValueType.String:
return (string)this.reference;

case JsonValueType.Null:
return null;

default:
return ThrowOrNull<string>();
}
Expand Down Expand Up @@ -272,24 +348,6 @@ public JsonArray? AsJsonArray
}
}

/// <summary>
/// Gets this value as a system.DateTime.
/// </summary>
public DateTime AsDateTime // it would never return an null datetime, even if theres no value on it.
{
get
{
if (this.IsString && DateTime.TryParse((string)this.reference, out DateTime value))
{
return value;
}
else
{
return ThrowOrNull<DateTime>();
}
}
}

/// <summary>
/// Gets this (inner) value as a System.object.
/// </summary>
Expand Down Expand Up @@ -438,7 +496,18 @@ private static JsonValue DetermineSingle(object? value, int deepness, out JsonVa
valueType = JsonValueType.Boolean;
return new JsonValue(valueType, nbool ? 1 : 0, null);
}
else if (value.GetType().IsArray)

foreach (var mapper in JsonOptions.Mappers)
{
if (mapper.CanSerialize(value))
{
var result = mapper.Serialize(value);
valueType = result.Type;
return result;
}
}

if (value.GetType().IsArray)
{
JsonArray arr = new JsonArray();
foreach (object? item in (IEnumerable)value)
Expand Down Expand Up @@ -628,24 +697,6 @@ public static implicit operator JsonValue(JsonArray value)
return new JsonValue(value);
}

/// <summary>
/// Converts the given DateTime? into a JsonValue.
/// </summary>
/// <remarks>
/// The DateTime value will be stored as a string using ISO 8601 format,
/// since JSON does not define a DateTime type.
/// </remarks>
/// <param name="value">The value to be converted.</param>
public static implicit operator JsonValue(DateTime? value)
{
if (value is null)
{
return JsonValue.Null;
}

return new JsonValue(value.Value.ToString("o"));
}

/// <summary>
/// Converts the given JsonValue into an Int.
/// </summary>
Expand Down Expand Up @@ -844,45 +895,6 @@ public static implicit operator double(JsonValue jsonValue)
}
}

/// <summary>
/// Converts the given JsonValue into a DateTime.
/// </summary>
/// <param name="jsonValue">The JsonValue to be converted.</param>
public static implicit operator DateTime(JsonValue jsonValue)
{
if (jsonValue.IsDateTime)
{
return jsonValue.AsDateTime;
}
else
{
if (JsonOptions.ThrowOnInvalidCast)
{
throw new InvalidCastException($"Cannot cast value of type {jsonValue.Type} to DateTime.");
}
else
{
return default;
}
}
}

/// <summary>
/// Converts the given JsonValue into a nullable DateTime.
/// </summary>
/// <param name="jsonValue">The JsonValue to be converted.</param>
public static implicit operator DateTime?(JsonValue jsonValue)
{
if (jsonValue.IsDateTime || jsonValue.IsNull)
{
return jsonValue.AsDateTime;
}
else
{
return null;
}
}

/// <summary>
/// Returns a value indicating whether the two given JsonValues are equal.
/// </summary>
Expand Down
2 changes: 0 additions & 2 deletions Sources/LightJson/LightJson.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@
<PropertyGroup>
<TargetFrameworks>
netcoreapp3.1;
netstandard1.6;
netstandard2.0;
netstandard2.1;
net35;
net452;
net462;
net472;
Expand Down

0 comments on commit 9f07a8f

Please sign in to comment.