From bed0eb9baada0aef65e9b7b5f250cdede8fb1183 Mon Sep 17 00:00:00 2001 From: kasperk81 <83082615+kasperk81@users.noreply.github.com> Date: Thu, 23 May 2024 21:03:46 +0300 Subject: [PATCH 1/3] Remove all LINQ usage from repo --- CHANGELOG.md | 6 ++ src/FormParseNode.cs | 41 ++++++++--- src/FormParseNodeFactory.cs | 4 ++ src/FormSerializationWriter.cs | 69 ++++++++++++------- src/FormSerializationWriterFactory.cs | 3 +- src/Microsoft.Kiota.Serialization.Form.csproj | 3 +- 6 files changed, 90 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index efc2f26..60c467a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [1.2.4] - 2024-05-23 + +### Changed + +- Remove all LINQ usage from repo + ## [1.2.3] - 2024-05-23 ### Changed diff --git a/src/FormParseNode.cs b/src/FormParseNode.cs index e9d0457..1ad0d52 100644 --- a/src/FormParseNode.cs +++ b/src/FormParseNode.cs @@ -1,6 +1,8 @@ using System.Diagnostics; using System.Reflection; using System.Xml; +using System; +using System.Collections.Generic; using Microsoft.Kiota.Abstractions; using Microsoft.Kiota.Abstractions.Extensions; using Microsoft.Kiota.Abstractions.Serialization; @@ -21,14 +23,29 @@ public class FormParseNode : IParseNode public FormParseNode(string rawValue) { RawValue = rawValue ?? throw new ArgumentNullException(nameof(rawValue)); - Fields = rawValue.Split(new char[] {'&'}, StringSplitOptions.RemoveEmptyEntries) - .Select(static x => x.Split(new char[] {'='}, StringSplitOptions.RemoveEmptyEntries)) - .Where(static x => x.Length == 2) - .Select(static x => (key: SanitizeKey(x[0]), value: x[1].Trim())) - .GroupBy(static x => x.key, StringComparer.OrdinalIgnoreCase) - .Select(static x => (key: x.Key, value: string.Join(",", x.Select(static y => y.value)))) - .ToDictionary(static x => x.key, static x => x.value, StringComparer.OrdinalIgnoreCase); + Fields = new Dictionary(StringComparer.OrdinalIgnoreCase); + char[] pairDelimiter = new char[] { '=' }; + string[] pairs = rawValue.Split(new char[] { '&' }, StringSplitOptions.RemoveEmptyEntries); + foreach (string pair in pairs) + { + string[] keyValue = pair.Split(pairDelimiter, StringSplitOptions.RemoveEmptyEntries); + if (keyValue.Length == 2) + { + string key = SanitizeKey(keyValue[0]); + string value = keyValue[1].Trim(); + + if (Fields.ContainsKey(key)) + { + Fields[key] += $",{value}"; + } + else + { + Fields.Add(key, value); + } + } + } } + private static string SanitizeKey(string key) { if (string.IsNullOrEmpty(key)) return key; return Uri.UnescapeDataString(key.Trim()); @@ -137,7 +154,7 @@ public T GetObjectValue(ParsableFactory factory) where T : IParsable { } private void AssignFieldValues(T item) where T : IParsable { - if(!Fields.Any()) return; + if(Fields.Count == 0) return; IDictionary? itemAdditionalData = null; if(item is IAdditionalDataHolder holder) { @@ -171,10 +188,13 @@ private void AssignFieldValues(T item) where T : IParsable } } } + /// public sbyte? GetSbyteValue() => sbyte.TryParse(DecodedValue, out var result) ? result : null; + /// public string GetStringValue() => DecodedValue; + /// public TimeSpan? GetTimeSpanValue() { var rawString = DecodedValue; @@ -184,8 +204,10 @@ private void AssignFieldValues(T item) where T : IParsable // Parse an ISO8601 duration.http://en.wikipedia.org/wiki/ISO_8601#Durations to a TimeSpan return XmlConvert.ToTimeSpan(rawString); } + /// public Time? GetTimeValue() => DateTime.TryParse(DecodedValue, out var result) ? new Time(result) : null; + #if NET5_0_OR_GREATER IEnumerable IParseNode.GetCollectionOfEnumValues<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] T>() #else @@ -195,6 +217,7 @@ private void AssignFieldValues(T item) where T : IParsable foreach (var v in DecodedValue.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) yield return GetEnumValueInternal(v); } + #if NET5_0_OR_GREATER T? IParseNode.GetEnumValue<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] T>() #else @@ -208,7 +231,7 @@ private void AssignFieldValues(T item) where T : IParsable { if(string.IsNullOrEmpty(rawValue)) return null; - if(typeof(T).GetCustomAttributes().Any()) + if (typeof(T).IsDefined(typeof(FlagsAttribute))) { ReadOnlySpan valueSpan = rawValue.AsSpan(); int value = 0; diff --git a/src/FormParseNodeFactory.cs b/src/FormParseNodeFactory.cs index 8a24c81..9fa4763 100644 --- a/src/FormParseNodeFactory.cs +++ b/src/FormParseNodeFactory.cs @@ -1,4 +1,8 @@ using Microsoft.Kiota.Abstractions.Serialization; +using System; +using System.IO; +using System.Threading; +using System.Threading.Tasks; namespace Microsoft.Kiota.Serialization.Form; diff --git a/src/FormSerializationWriter.cs b/src/FormSerializationWriter.cs index a4fe0b4..b83e4c2 100644 --- a/src/FormSerializationWriter.cs +++ b/src/FormSerializationWriter.cs @@ -5,9 +5,12 @@ using Microsoft.Kiota.Abstractions; using Microsoft.Kiota.Abstractions.Extensions; using Microsoft.Kiota.Abstractions.Serialization; +using System.IO; #if NET5_0_OR_GREATER using System.Diagnostics.CodeAnalysis; #endif +using System; +using System.Collections.Generic; namespace Microsoft.Kiota.Serialization.Form; /// Represents a serialization writer that can be used to write a form url encoded string. @@ -89,30 +92,38 @@ private void WriteAnyValue(string? key, object value) } } + /// public void WriteBoolValue(string? key, bool? value) { if(value.HasValue) WriteStringValue(key, value.Value.ToString().ToLowerInvariant()); } + /// public void WriteByteArrayValue(string? key, byte[]? value) { if(value != null)//empty array is meaningful WriteStringValue(key, value.Length > 0 ? Convert.ToBase64String(value) : string.Empty); } + /// public void WriteByteValue(string? key, byte? value) { if(value.HasValue) WriteIntValue(key, Convert.ToInt32(value.Value)); } + /// public void WriteCollectionOfObjectValues(string? key, IEnumerable? values) where T : IParsable => throw new InvalidOperationException("Form serialization does not support collections."); + /// - public void WriteCollectionOfPrimitiveValues(string? key, IEnumerable? values) +public void WriteCollectionOfPrimitiveValues(string? key, IEnumerable? values) +{ + if (values == null) return; + foreach (var value in values) { - if(values == null) return; - foreach(var value in values.Where(static x => x != null)) - WriteAnyValue(key,value!); + if (value != null) + WriteAnyValue(key, value); } +} /// public void WriteDateTimeOffsetValue(string? key, DateTimeOffset? value) { if(value.HasValue) @@ -162,18 +173,27 @@ public void WriteObjectValue(string? key, T? value, params IParsable?[] addit { if(depth > 0) throw new InvalidOperationException("Form serialization does not support nested objects."); depth++; - if(value == null && !additionalValuesToMerge.Any(static x => x != null)) return; + if (value == null) + { + foreach (var x in additionalValuesToMerge) + { + if (x != null) break; + } + } + if(value != null) { OnBeforeObjectSerialization?.Invoke(value); OnStartObjectSerialization?.Invoke(value, this); value.Serialize(this); } - foreach(var additionalValueToMerge in additionalValuesToMerge.Where(static x => x != null)) + foreach (var additionalValueToMerge in additionalValuesToMerge) { - OnBeforeObjectSerialization?.Invoke(additionalValueToMerge!); - OnStartObjectSerialization?.Invoke(additionalValueToMerge!, this); - additionalValueToMerge!.Serialize(this); - OnAfterObjectSerialization?.Invoke(additionalValueToMerge!); + if (additionalValueToMerge is null) continue; + + OnBeforeObjectSerialization?.Invoke(additionalValueToMerge); + OnStartObjectSerialization?.Invoke(additionalValueToMerge, this); + additionalValueToMerge.Serialize(this); + OnAfterObjectSerialization?.Invoke(additionalValueToMerge); } if(value != null) OnAfterObjectSerialization?.Invoke(value); @@ -206,24 +226,25 @@ public void WriteTimeValue(string? key, Time? value) { public void WriteCollectionOfEnumValues(string? key, IEnumerable? values) where T : struct, Enum #endif { - if(values == null) return; + if (values is null) return; - StringBuilder? valueNames = null; - foreach(var x in values) + using (var enumerator = values.GetEnumerator()) { - if(x.HasValue && Enum.GetName(typeof(T), x.Value) is string valueName) + if (!enumerator.MoveNext()) return; + } + + List nonNullValues = new List(); + foreach (var value in values) + { + if (value.HasValue) { - if(valueNames == null) - valueNames = new StringBuilder(); - else - valueNames.Append(","); - valueNames.Append(valueName.ToFirstCharacterLowerCase()); + nonNullValues.Add(value.Value.ToString().ToFirstCharacterLowerCase()!); } } - if(valueNames is not null) - WriteStringValue(key, valueNames.ToString()); + WriteStringValue(key, string.Join(",", nonNullValues)); } + /// #if NET5_0_OR_GREATER public void WriteEnumValue<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] T>(string? key, T? value) where T : struct, Enum @@ -233,13 +254,13 @@ public void WriteEnumValue(string? key, T? value) where T : struct, Enum { if(value.HasValue) { - if(typeof(T).GetCustomAttributes().Any()) + if (typeof(T).IsDefined(typeof(FlagsAttribute))) { - var values = + T[] values = #if NET5_0_OR_GREATER Enum.GetValues(); #else - Enum.GetValues(typeof(T)).Cast(); + (T[])Enum.GetValues(typeof(T)); #endif StringBuilder valueNames = new StringBuilder(); foreach(var x in values) diff --git a/src/FormSerializationWriterFactory.cs b/src/FormSerializationWriterFactory.cs index aaf4577..46201f5 100644 --- a/src/FormSerializationWriterFactory.cs +++ b/src/FormSerializationWriterFactory.cs @@ -1,4 +1,5 @@ using Microsoft.Kiota.Abstractions.Serialization; +using System; namespace Microsoft.Kiota.Serialization.Form; /// Represents a serialization writer factory that can be used to create a form url encoded serialization writer. @@ -14,4 +15,4 @@ public ISerializationWriter GetSerializationWriter(string contentType) { throw new ArgumentOutOfRangeException($"expected a {ValidContentType} content type"); return new FormSerializationWriter(); } -} \ No newline at end of file +} diff --git a/src/Microsoft.Kiota.Serialization.Form.csproj b/src/Microsoft.Kiota.Serialization.Form.csproj index 3baf810..72b5486 100644 --- a/src/Microsoft.Kiota.Serialization.Form.csproj +++ b/src/Microsoft.Kiota.Serialization.Form.csproj @@ -8,7 +8,6 @@ Microsoft netstandard2.0;netstandard2.1;net5.0;net6.0;net8.0 latest - enable enable true http://go.microsoft.com/fwlink/?LinkID=288890 @@ -16,7 +15,7 @@ https://aka.ms/kiota/docs true true - 1.2.3 + 1.2.4 true true From 987a7406a855d47a30b54b40c12da7108b330219 Mon Sep 17 00:00:00 2001 From: kasperk81 <83082615+kasperk81@users.noreply.github.com> Date: Fri, 24 May 2024 15:29:48 +0300 Subject: [PATCH 2/3] Update FormSerializationWriter.cs --- src/FormSerializationWriter.cs | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/src/FormSerializationWriter.cs b/src/FormSerializationWriter.cs index b83e4c2..2ddf467 100644 --- a/src/FormSerializationWriter.cs +++ b/src/FormSerializationWriter.cs @@ -173,13 +173,7 @@ public void WriteObjectValue(string? key, T? value, params IParsable?[] addit { if(depth > 0) throw new InvalidOperationException("Form serialization does not support nested objects."); depth++; - if (value == null) - { - foreach (var x in additionalValuesToMerge) - { - if (x != null) break; - } - } + if (value == null && !Array.Exists(additionalValuesToMerge, static x => x is not null)) return; if(value != null) { OnBeforeObjectSerialization?.Invoke(value); @@ -226,23 +220,23 @@ public void WriteTimeValue(string? key, Time? value) { public void WriteCollectionOfEnumValues(string? key, IEnumerable? values) where T : struct, Enum #endif { - if (values is null) return; - - using (var enumerator = values.GetEnumerator()) - { - if (!enumerator.MoveNext()) return; - } + if(values == null) return; - List nonNullValues = new List(); - foreach (var value in values) + StringBuilder? valueNames = null; + foreach(var x in values) { - if (value.HasValue) + if(x.HasValue && Enum.GetName(typeof(T), x.Value) is string valueName) { - nonNullValues.Add(value.Value.ToString().ToFirstCharacterLowerCase()!); + if(valueNames == null) + valueNames = new StringBuilder(); + else + valueNames.Append(","); + valueNames.Append(valueName.ToFirstCharacterLowerCase()); } } - WriteStringValue(key, string.Join(",", nonNullValues)); + if(valueNames is not null) + WriteStringValue(key, valueNames.ToString()); } /// From d8288fd76167348e74f281bae046409c17e56d84 Mon Sep 17 00:00:00 2001 From: kasperk81 <83082615+kasperk81@users.noreply.github.com> Date: Fri, 24 May 2024 15:30:55 +0300 Subject: [PATCH 3/3] Update FormSerializationWriter.cs --- src/FormSerializationWriter.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/FormSerializationWriter.cs b/src/FormSerializationWriter.cs index 2ddf467..a2ee044 100644 --- a/src/FormSerializationWriter.cs +++ b/src/FormSerializationWriter.cs @@ -115,15 +115,16 @@ public void WriteByteValue(string? key, byte? value) { public void WriteCollectionOfObjectValues(string? key, IEnumerable? values) where T : IParsable => throw new InvalidOperationException("Form serialization does not support collections."); /// -public void WriteCollectionOfPrimitiveValues(string? key, IEnumerable? values) -{ - if (values == null) return; - foreach (var value in values) + public void WriteCollectionOfPrimitiveValues(string? key, IEnumerable? values) { - if (value != null) - WriteAnyValue(key, value); + if (values == null) return; + foreach (var value in values) + { + if (value != null) + WriteAnyValue(key, value); + } } -} + /// public void WriteDateTimeOffsetValue(string? key, DateTimeOffset? value) { if(value.HasValue)