Skip to content
This repository has been archived by the owner on Jul 9, 2024. It is now read-only.

Commit

Permalink
Merge pull request #58 from microsoft/andrueastman/NRT
Browse files Browse the repository at this point in the history
Adds support for nullable reference types
  • Loading branch information
andrueastman authored Jan 17, 2023
2 parents ffc7ecc + 5814f8c commit c6b0dd3
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 89 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

## [1.0.0-rc.2] - 2023-01-17

### Changed

- Adds support for nullable reference types

## [1.0.0-rc.1] - 2022-12-15

### Changed
Expand Down
73 changes: 36 additions & 37 deletions src/JsonParseNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public JsonParseNode(JsonElement node)
/// Get the string value from the json node
/// </summary>
/// <returns>A string value</returns>
public string GetStringValue() => _jsonNode.ValueKind == JsonValueKind.String ? _jsonNode.GetString() : null;
public string? GetStringValue() => _jsonNode.ValueKind == JsonValueKind.String ? _jsonNode.GetString() : null;

/// <summary>
/// Get the boolean value from the json node
Expand Down Expand Up @@ -99,7 +99,7 @@ public JsonParseNode(JsonElement node)
// JsonElement.GetDateTimeOffset is super strict so try to be more lenient if it fails(e.g. when we have whitespace or other variant formats).
// ref - https://docs.microsoft.com/en-us/dotnet/standard/datetime/system-text-json-support
if(!_jsonNode.TryGetDateTimeOffset(out var value))
value = DateTimeOffset.Parse(_jsonNode.GetString());
value = DateTimeOffset.Parse(_jsonNode.GetString()!);

return value;
}
Expand Down Expand Up @@ -154,11 +154,11 @@ public JsonParseNode(JsonElement node)
if(string.IsNullOrEmpty(rawValue)) return null;
if(typeof(T).GetCustomAttributes<FlagsAttribute>().Any())
{
return (T)(object)rawValue
return (T)(object)rawValue!
.Split(',')
.Select(x => Enum.TryParse<T>(x, true, out var result) ? result : (T?)null)
.Where(x => !x.Equals(null))
.Select(x => (int)(object)x)
.Select(x => (int)(object)x!)
.Sum();
}
else
Expand Down Expand Up @@ -208,23 +208,23 @@ public IEnumerable<T> GetCollectionOfObjectValues<T>(ParsableFactory<T> factory)
/// Gets the byte array value of the node.
/// </summary>
/// <returns>The byte array value of the node.</returns>
public byte[] GetByteArrayValue() {
public byte[]? GetByteArrayValue() {
var rawValue = _jsonNode.GetString();
if(string.IsNullOrEmpty(rawValue)) return null;
return Convert.FromBase64String(rawValue);
}
private static Type booleanType = typeof(bool?);
private static Type byteType = typeof(byte?);
private static Type sbyteType = typeof(sbyte?);
private static Type stringType = typeof(string);
private static Type intType = typeof(int?);
private static Type floatType = typeof(float?);
private static Type doubleType = typeof(double?);
private static Type guidType = typeof(Guid?);
private static Type dateTimeOffsetType = typeof(DateTimeOffset?);
private static Type timeSpanType = typeof(TimeSpan?);
private static Type dateType = typeof(Date?);
private static Type timeType = typeof(Time?);
private static readonly Type booleanType = typeof(bool?);
private static readonly Type byteType = typeof(byte?);
private static readonly Type sbyteType = typeof(sbyte?);
private static readonly Type stringType = typeof(string);
private static readonly Type intType = typeof(int?);
private static readonly Type floatType = typeof(float?);
private static readonly Type doubleType = typeof(double?);
private static readonly Type guidType = typeof(Guid?);
private static readonly Type dateTimeOffsetType = typeof(DateTimeOffset?);
private static readonly Type timeSpanType = typeof(TimeSpan?);
private static readonly Type dateType = typeof(Date?);
private static readonly Type timeType = typeof(Time?);

/// <summary>
/// Get the collection of primitives of type <typeparam name="T"/>from the json node
Expand All @@ -242,29 +242,29 @@ public IEnumerable<T> GetCollectionOfPrimitiveValues<T>()
OnAfterAssignFieldValues = OnAfterAssignFieldValues
};
if(genericType == booleanType)
yield return (T)(object)currentParseNode.GetBoolValue();
yield return (T)(object)currentParseNode.GetBoolValue()!;
else if(genericType == byteType)
yield return (T)(object)currentParseNode.GetByteValue();
yield return (T)(object)currentParseNode.GetByteValue()!;
else if(genericType == sbyteType)
yield return (T)(object)currentParseNode.GetSbyteValue();
yield return (T)(object)currentParseNode.GetSbyteValue()!;
else if(genericType == stringType)
yield return (T)(object)currentParseNode.GetStringValue();
yield return (T)(object)currentParseNode.GetStringValue()!;
else if(genericType == intType)
yield return (T)(object)currentParseNode.GetIntValue();
yield return (T)(object)currentParseNode.GetIntValue()!;
else if(genericType == floatType)
yield return (T)(object)currentParseNode.GetFloatValue();
yield return (T)(object)currentParseNode.GetFloatValue()!;
else if(genericType == doubleType)
yield return (T)(object)currentParseNode.GetDoubleValue();
yield return (T)(object)currentParseNode.GetDoubleValue()!;
else if(genericType == guidType)
yield return (T)(object)currentParseNode.GetGuidValue();
yield return (T)(object)currentParseNode.GetGuidValue()!;
else if(genericType == dateTimeOffsetType)
yield return (T)(object)currentParseNode.GetDateTimeOffsetValue();
yield return (T)(object)currentParseNode.GetDateTimeOffsetValue()!;
else if(genericType == timeSpanType)
yield return (T)(object)currentParseNode.GetTimeSpanValue();
yield return (T)(object)currentParseNode.GetTimeSpanValue()!;
else if(genericType == dateType)
yield return (T)(object)currentParseNode.GetDateValue();
yield return (T)(object)currentParseNode.GetDateValue()!;
else if(genericType == timeType)
yield return (T)(object)currentParseNode.GetTimeValue();
yield return (T)(object)currentParseNode.GetTimeValue()!;
else
throw new InvalidOperationException($"unknown type for deserialization {genericType.FullName}");
}
Expand All @@ -274,12 +274,12 @@ public IEnumerable<T> GetCollectionOfPrimitiveValues<T>()
/// <summary>
/// The action to perform before assigning field values.
/// </summary>
public Action<IParsable> OnBeforeAssignFieldValues { get; set; }
public Action<IParsable>? OnBeforeAssignFieldValues { get; set; }

/// <summary>
/// The action to perform after assigning field values.
/// </summary>
public Action<IParsable> OnAfterAssignFieldValues { get; set; }
public Action<IParsable>? OnAfterAssignFieldValues { get; set; }

/// <summary>
/// Get the object of type <typeparam name="T"/>from the json node
Expand All @@ -297,11 +297,10 @@ public T GetObjectValue<T>(ParsableFactory<T> factory) where T : IParsable
private void AssignFieldValues<T>(T item) where T : IParsable
{
if(_jsonNode.ValueKind != JsonValueKind.Object) return;
IDictionary<string, object> itemAdditionalData = null;
IDictionary<string, object>? itemAdditionalData = null;
if(item is IAdditionalDataHolder holder)
{
if(holder.AdditionalData == null)
holder.AdditionalData = new Dictionary<string, object>();
holder.AdditionalData ??= new Dictionary<string, object>();
itemAdditionalData = holder.AdditionalData;
}
var fieldDeserializers = item.GetFieldDeserializers();
Expand All @@ -324,15 +323,15 @@ private void AssignFieldValues<T>(T item) where T : IParsable
else if (itemAdditionalData != null)
{
Debug.WriteLine($"found additional property {fieldValue.Name} to deserialize");
itemAdditionalData.TryAdd(fieldValue.Name, TryGetAnything(fieldValue.Value));
IDictionaryExtensions.TryAdd(itemAdditionalData, fieldValue.Name, TryGetAnything(fieldValue.Value)!);
}
else
{
Debug.WriteLine($"found additional property {fieldValue.Name} to deserialize but the model doesn't support additional data");
}
}
}
private object TryGetAnything(JsonElement element)
private static object? TryGetAnything(JsonElement element)
{
switch(element.ValueKind)
{
Expand Down Expand Up @@ -372,7 +371,7 @@ private object TryGetAnything(JsonElement element)
/// </summary>
/// <param name="identifier">The identifier of the child node</param>
/// <returns>An instance of <see cref="IParseNode"/></returns>
public IParseNode GetChildNode(string identifier)
public IParseNode? GetChildNode(string identifier)
{
if(_jsonNode.ValueKind == JsonValueKind.Object && _jsonNode.TryGetProperty(identifier ?? throw new ArgumentNullException(nameof(identifier)), out var jsonElement))
{
Expand Down
Loading

0 comments on commit c6b0dd3

Please sign in to comment.