diff --git a/CHANGELOG.md b/CHANGELOG.md index b89fd23..83f2e29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/src/JsonParseNode.cs b/src/JsonParseNode.cs index 426d9d5..b47124d 100644 --- a/src/JsonParseNode.cs +++ b/src/JsonParseNode.cs @@ -34,7 +34,7 @@ public JsonParseNode(JsonElement node) /// Get the string value from the json node /// /// A string value - public string GetStringValue() => _jsonNode.ValueKind == JsonValueKind.String ? _jsonNode.GetString() : null; + public string? GetStringValue() => _jsonNode.ValueKind == JsonValueKind.String ? _jsonNode.GetString() : null; /// /// Get the boolean value from the json node @@ -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; } @@ -154,11 +154,11 @@ public JsonParseNode(JsonElement node) if(string.IsNullOrEmpty(rawValue)) return null; if(typeof(T).GetCustomAttributes().Any()) { - return (T)(object)rawValue + return (T)(object)rawValue! .Split(',') .Select(x => Enum.TryParse(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 @@ -208,23 +208,23 @@ public IEnumerable GetCollectionOfObjectValues(ParsableFactory factory) /// Gets the byte array value of the node. /// /// The byte array value of the node. - 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?); /// /// Get the collection of primitives of type from the json node @@ -242,29 +242,29 @@ public IEnumerable GetCollectionOfPrimitiveValues() 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}"); } @@ -274,12 +274,12 @@ public IEnumerable GetCollectionOfPrimitiveValues() /// /// The action to perform before assigning field values. /// - public Action OnBeforeAssignFieldValues { get; set; } + public Action? OnBeforeAssignFieldValues { get; set; } /// /// The action to perform after assigning field values. /// - public Action OnAfterAssignFieldValues { get; set; } + public Action? OnAfterAssignFieldValues { get; set; } /// /// Get the object of type from the json node @@ -297,11 +297,10 @@ public T GetObjectValue(ParsableFactory factory) where T : IParsable private void AssignFieldValues(T item) where T : IParsable { if(_jsonNode.ValueKind != JsonValueKind.Object) return; - IDictionary itemAdditionalData = null; + IDictionary? itemAdditionalData = null; if(item is IAdditionalDataHolder holder) { - if(holder.AdditionalData == null) - holder.AdditionalData = new Dictionary(); + holder.AdditionalData ??= new Dictionary(); itemAdditionalData = holder.AdditionalData; } var fieldDeserializers = item.GetFieldDeserializers(); @@ -324,7 +323,7 @@ private void AssignFieldValues(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 { @@ -332,7 +331,7 @@ private void AssignFieldValues(T item) where T : IParsable } } } - private object TryGetAnything(JsonElement element) + private static object? TryGetAnything(JsonElement element) { switch(element.ValueKind) { @@ -372,7 +371,7 @@ private object TryGetAnything(JsonElement element) /// /// The identifier of the child node /// An instance of - 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)) { diff --git a/src/JsonSerializationWriter.cs b/src/JsonSerializationWriter.cs index be9d1f5..f1d8382 100644 --- a/src/JsonSerializationWriter.cs +++ b/src/JsonSerializationWriter.cs @@ -38,17 +38,17 @@ public JsonSerializationWriter() /// /// The action to perform before object serialization /// - public Action OnBeforeObjectSerialization { get; set; } + public Action? OnBeforeObjectSerialization { get; set; } /// /// The action to perform after object serialization /// - public Action OnAfterObjectSerialization { get; set; } + public Action? OnAfterObjectSerialization { get; set; } /// /// The action to perform on the start of object serialization /// - public Action OnStartObjectSerialization { get; set; } + public Action? OnStartObjectSerialization { get; set; } /// /// Get the stream of the serialized content @@ -65,11 +65,11 @@ public Stream GetSerializedContent() { /// /// The key of the json node /// The string value - public void WriteStringValue(string key, string value) + public void WriteStringValue(string? key, string? value) { if(value != null) { // we want to keep empty string because they are meaningful - if(!string.IsNullOrEmpty(key)) writer.WritePropertyName(key); + if(!string.IsNullOrEmpty(key)) writer.WritePropertyName(key!); writer.WriteStringValue(value); } } @@ -79,9 +79,9 @@ public void WriteStringValue(string key, string value) /// /// The key of the json node /// The boolean value - public void WriteBoolValue(string key, bool? value) + public void WriteBoolValue(string? key, bool? value) { - if(!string.IsNullOrEmpty(key) && value.HasValue) writer.WritePropertyName(key); + if(!string.IsNullOrEmpty(key) && value.HasValue) writer.WritePropertyName(key!); if(value.HasValue) writer.WriteBooleanValue(value.Value); } @@ -90,9 +90,9 @@ public void WriteBoolValue(string key, bool? value) /// /// The key of the json node /// The byte value - public void WriteByteValue(string key, byte? value) + public void WriteByteValue(string? key, byte? value) { - if(!string.IsNullOrEmpty(key) && value.HasValue) writer.WritePropertyName(key); + if(!string.IsNullOrEmpty(key) && value.HasValue) writer.WritePropertyName(key!); if(value.HasValue) writer.WriteNumberValue(Convert.ToInt32(value.Value)); } @@ -101,9 +101,9 @@ public void WriteByteValue(string key, byte? value) /// /// The key of the json node /// The sbyte value - public void WriteSbyteValue(string key, sbyte? value) + public void WriteSbyteValue(string? key, sbyte? value) { - if(!string.IsNullOrEmpty(key) && value.HasValue) writer.WritePropertyName(key); + if(!string.IsNullOrEmpty(key) && value.HasValue) writer.WritePropertyName(key!); if(value.HasValue) writer.WriteNumberValue(Convert.ToInt32(value.Value)); } @@ -112,9 +112,9 @@ public void WriteSbyteValue(string key, sbyte? value) /// /// The key of the json node /// The int value - public void WriteIntValue(string key, int? value) + public void WriteIntValue(string? key, int? value) { - if(!string.IsNullOrEmpty(key) && value.HasValue) writer.WritePropertyName(key); + if(!string.IsNullOrEmpty(key) && value.HasValue) writer.WritePropertyName(key!); if(value.HasValue) writer.WriteNumberValue(value.Value); } @@ -123,9 +123,9 @@ public void WriteIntValue(string key, int? value) /// /// The key of the json node /// The float value - public void WriteFloatValue(string key, float? value) + public void WriteFloatValue(string? key, float? value) { - if(!string.IsNullOrEmpty(key) && value.HasValue) writer.WritePropertyName(key); + if(!string.IsNullOrEmpty(key) && value.HasValue) writer.WritePropertyName(key!); if(value.HasValue) writer.WriteNumberValue(value.Value); } @@ -134,9 +134,9 @@ public void WriteFloatValue(string key, float? value) /// /// The key of the json node /// The long value - public void WriteLongValue(string key, long? value) + public void WriteLongValue(string? key, long? value) { - if(!string.IsNullOrEmpty(key) && value.HasValue) writer.WritePropertyName(key); + if(!string.IsNullOrEmpty(key) && value.HasValue) writer.WritePropertyName(key!); if(value.HasValue) writer.WriteNumberValue(value.Value); } @@ -145,9 +145,9 @@ public void WriteLongValue(string key, long? value) /// /// The key of the json node /// The double value - public void WriteDoubleValue(string key, double? value) + public void WriteDoubleValue(string? key, double? value) { - if(!string.IsNullOrEmpty(key) && value.HasValue) writer.WritePropertyName(key); + if(!string.IsNullOrEmpty(key) && value.HasValue) writer.WritePropertyName(key!); if(value.HasValue) writer.WriteNumberValue(value.Value); } @@ -156,9 +156,9 @@ public void WriteDoubleValue(string key, double? value) /// /// The key of the json node /// The decimal value - public void WriteDecimalValue(string key, decimal? value) + public void WriteDecimalValue(string? key, decimal? value) { - if(!string.IsNullOrEmpty(key) && value.HasValue) writer.WritePropertyName(key); + if(!string.IsNullOrEmpty(key) && value.HasValue) writer.WritePropertyName(key!); if(value.HasValue) writer.WriteNumberValue(value.Value); } @@ -167,9 +167,9 @@ public void WriteDecimalValue(string key, decimal? value) /// /// The key of the json node /// The Guid value - public void WriteGuidValue(string key, Guid? value) + public void WriteGuidValue(string? key, Guid? value) { - if(!string.IsNullOrEmpty(key) && value.HasValue) writer.WritePropertyName(key); + if(!string.IsNullOrEmpty(key) && value.HasValue) writer.WritePropertyName(key!); if(value.HasValue) writer.WriteStringValue(value.Value); } @@ -178,9 +178,9 @@ public void WriteGuidValue(string key, Guid? value) /// /// The key of the json node /// The DateTimeOffset value - public void WriteDateTimeOffsetValue(string key, DateTimeOffset? value) + public void WriteDateTimeOffsetValue(string? key, DateTimeOffset? value) { - if(!string.IsNullOrEmpty(key) && value.HasValue) writer.WritePropertyName(key); + if(!string.IsNullOrEmpty(key) && value.HasValue) writer.WritePropertyName(key!); if(value.HasValue) writer.WriteStringValue(value.Value); } @@ -189,9 +189,9 @@ public void WriteDateTimeOffsetValue(string key, DateTimeOffset? value) /// /// The key of the json node /// The TimeSpan value - public void WriteTimeSpanValue(string key, TimeSpan? value) + public void WriteTimeSpanValue(string? key, TimeSpan? value) { - if(!string.IsNullOrEmpty(key) && value.HasValue) writer.WritePropertyName(key); + if(!string.IsNullOrEmpty(key) && value.HasValue) writer.WritePropertyName(key!); if(value.HasValue) writer.WriteStringValue(XmlConvert.ToString(value.Value)); } @@ -200,9 +200,9 @@ public void WriteTimeSpanValue(string key, TimeSpan? value) /// /// The key of the json node /// The Date value - public void WriteDateValue(string key, Date? value) + public void WriteDateValue(string? key, Date? value) { - if(!string.IsNullOrEmpty(key) && value.HasValue) writer.WritePropertyName(key); + if(!string.IsNullOrEmpty(key) && value.HasValue) writer.WritePropertyName(key!); if(value.HasValue) writer.WriteStringValue(value.Value.ToString()); } @@ -211,9 +211,9 @@ public void WriteDateValue(string key, Date? value) /// /// The key of the json node /// The Time value - public void WriteTimeValue(string key, Time? value) + public void WriteTimeValue(string? key, Time? value) { - if(!string.IsNullOrEmpty(key) && value.HasValue) writer.WritePropertyName(key); + if(!string.IsNullOrEmpty(key) && value.HasValue) writer.WritePropertyName(key!); if(value.HasValue) writer.WriteStringValue(value.Value.ToString()); } @@ -221,9 +221,9 @@ public void WriteTimeValue(string key, Time? value) /// Write the null value /// /// The key of the json node - public void WriteNullValue(string key) + public void WriteNullValue(string? key) { - if(!string.IsNullOrEmpty(key)) writer.WritePropertyName(key); + if(!string.IsNullOrEmpty(key)) writer.WritePropertyName(key!); writer.WriteNullValue(); } @@ -232,9 +232,9 @@ public void WriteNullValue(string key) /// /// The key of the json node /// The enumeration value - public void WriteEnumValue(string key, T? value) where T : struct, Enum + public void WriteEnumValue(string? key, T? value) where T : struct, Enum { - if(!string.IsNullOrEmpty(key) && value.HasValue) writer.WritePropertyName(key); + if(!string.IsNullOrEmpty(key) && value.HasValue) writer.WritePropertyName(key!); if(value.HasValue) { if(typeof(T).GetCustomAttributes().Any()) @@ -253,11 +253,11 @@ public void WriteEnumValue(string key, T? value) where T : struct, Enum /// /// The key of the json node /// The primitive collection - public void WriteCollectionOfPrimitiveValues(string key, IEnumerable values) + public void WriteCollectionOfPrimitiveValues(string? key, IEnumerable? values) { if(values != null) { //empty array is meaningful - if(!string.IsNullOrEmpty(key)) writer.WritePropertyName(key); + if(!string.IsNullOrEmpty(key)) writer.WritePropertyName(key!); writer.WriteStartArray(); foreach(var collectionValue in values) WriteAnyValue(null, collectionValue); @@ -270,11 +270,11 @@ public void WriteCollectionOfPrimitiveValues(string key, IEnumerable value /// /// The key of the json node /// The object collection - public void WriteCollectionOfObjectValues(string key, IEnumerable values) where T : IParsable + public void WriteCollectionOfObjectValues(string? key, IEnumerable? values) where T : IParsable { if(values != null) { //empty array is meaningful - if(!string.IsNullOrEmpty(key)) writer.WritePropertyName(key); + if(!string.IsNullOrEmpty(key)) writer.WritePropertyName(key!); writer.WriteStartArray(); foreach(var item in values) WriteObjectValue(null, item); @@ -286,11 +286,11 @@ public void WriteCollectionOfObjectValues(string key, IEnumerable values) /// /// The key to be used for the written value. May be null. /// The enum values to be written. - public void WriteCollectionOfEnumValues(string key, IEnumerable values) where T : struct, Enum + public void WriteCollectionOfEnumValues(string? key, IEnumerable? values) where T : struct, Enum { if(values != null) { //empty array is meaningful - if(!string.IsNullOrEmpty(key)) writer.WritePropertyName(key); + if(!string.IsNullOrEmpty(key)) writer.WritePropertyName(key!); writer.WriteStartArray(); foreach(var item in values) WriteEnumValue(null, item); @@ -302,7 +302,7 @@ public void WriteCollectionOfEnumValues(string key, IEnumerable values) w /// /// The key to be used for the written value. May be null. /// The byte array to be written. - public void WriteByteArrayValue(string key, byte[] value) + public void WriteByteArrayValue(string? key, byte[]? value) { if(value != null)//empty array is meaningful WriteStringValue(key, value.Any() ? Convert.ToBase64String(value) : string.Empty); @@ -314,11 +314,11 @@ public void WriteByteArrayValue(string key, byte[] value) /// The key of the json node /// The object instance to write /// The additional values to merge to the main value when serializing an intersection wrapper. - public void WriteObjectValue(string key, T value, params IParsable[] additionalValuesToMerge) where T : IParsable + public void WriteObjectValue(string? key, T? value, params IParsable[] additionalValuesToMerge) where T : IParsable { if(value != null || additionalValuesToMerge.Any(static x => x != null)) { - if(!string.IsNullOrEmpty(key)) writer.WritePropertyName(key); + if(!string.IsNullOrEmpty(key)) writer.WritePropertyName(key!); if(value != null) OnBeforeObjectSerialization?.Invoke(value); writer.WriteStartObject(); if(value != null) { @@ -349,10 +349,10 @@ public void WriteAdditionalData(IDictionary value) WriteAnyValue(dataValue.Key, dataValue.Value); } - private void WriteNonParsableObjectValue(string key, T value) + private void WriteNonParsableObjectValue(string? key, T value) { if(!string.IsNullOrEmpty(key)) - writer.WritePropertyName(key); + writer.WritePropertyName(key!); writer.WriteStartObject(); if(value == null) writer.WriteNullValue(); else @@ -360,7 +360,7 @@ private void WriteNonParsableObjectValue(string key, T value) WriteAnyValue(oProp.Name, oProp.GetValue(value)); writer.WriteEndObject(); } - private void WriteAnyValue(string key, T value) + private void WriteAnyValue(string? key, T value) { switch(value) { @@ -410,7 +410,7 @@ private void WriteAnyValue(string key, T value) WriteTimeValue(key, time); break; case JsonElement jsonElement: - if(!string.IsNullOrEmpty(key)) writer.WritePropertyName(key); + if(!string.IsNullOrEmpty(key)) writer.WritePropertyName(key!); jsonElement.WriteTo(writer); break; case object o: diff --git a/src/Microsoft.Kiota.Serialization.Json.csproj b/src/Microsoft.Kiota.Serialization.Json.csproj index b8101ac..d76312c 100644 --- a/src/Microsoft.Kiota.Serialization.Json.csproj +++ b/src/Microsoft.Kiota.Serialization.Json.csproj @@ -1,4 +1,4 @@ - + @@ -6,7 +6,7 @@ © Microsoft Corporation. All rights reserved. Kiota JSON Serialization Library for dotnet using System.Text.Json Microsoft - netstandard2.0 + netstandard2.0;netstandard2.1 latest true https://github.com/microsoft/kiota-serialization-json-dotnet @@ -23,8 +23,11 @@ false 35MSSharedLib1024.snk - - Release candidate 1. + https://github.com/microsoft/kiota-serialization-json-dotnet/releases + latest + enable + true true LICENSE README.md @@ -32,7 +35,7 @@ - +