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 #143 from filipnavara/enum-aot
Browse files Browse the repository at this point in the history
Remove LINQ usage from Enum conversion from/to string
  • Loading branch information
andrueastman authored May 20, 2024
2 parents 0b0f1f7 + 53d1f1c commit 087222f
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 17 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [1.2.1] - 2024-05-20

### Changed

- Updated serialization and deserialization of enums to remove LINQ to resolve NativeAOT compatibility issue

## [1.2.0] - 2024-05-13

### Added
Expand Down
27 changes: 18 additions & 9 deletions src/FormParseNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -203,20 +203,29 @@ private void AssignFieldValues<T>(T item) where T : IParsable
return GetEnumValueInternal<T>(DecodedValue);
}

private static T? GetEnumValueInternal<T>(string value) where T : struct, Enum
private static T? GetEnumValueInternal<T>(string rawValue) where T : struct, Enum
{
if(string.IsNullOrEmpty(value))
if(string.IsNullOrEmpty(rawValue))
return null;
if(typeof(T).GetCustomAttributes<FlagsAttribute>().Any())
{
return (T)(object)value
.Split(',')
.Select(static x => Enum.TryParse<T>(x, true, out var result) ? result : (T?)null)
.Where(static x => x is not null)
.Select(x => (int)((object)x!))
.Sum();
ReadOnlySpan<char> valueSpan = rawValue.AsSpan();
int value = 0;
while(valueSpan.Length > 0)
{
int commaIndex = valueSpan.IndexOf(',');
ReadOnlySpan<char> valueNameSpan = commaIndex < 0 ? valueSpan : valueSpan.Slice(0, commaIndex);
#if NET6_0_OR_GREATER
if(Enum.TryParse<T>(valueNameSpan, true, out var result))
#else
if(Enum.TryParse<T>(valueNameSpan.ToString(), true, out var result))
#endif
value |= (int)(object)result;
valueSpan = commaIndex < 0 ? ReadOnlySpan<char>.Empty : valueSpan.Slice(commaIndex + 1);
}
return (T)(object)value;
}
if(Enum.TryParse<T>(value, out var result))
else if(Enum.TryParse<T>(rawValue, out var result))
return result;
return null;
}
Expand Down
23 changes: 16 additions & 7 deletions src/FormSerializationWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -220,16 +220,25 @@ public void WriteEnumValue<T>(string? key, T? value) where T : struct, Enum
if(value.HasValue)
{
if(typeof(T).GetCustomAttributes<FlagsAttribute>().Any())
WriteStringValue(key, string.Join(",",
{
var values =
#if NET5_0_OR_GREATER
Enum.GetValues<T>()
Enum.GetValues<T>();
#else
Enum.GetValues(typeof(T))
.Cast<T>()
Enum.GetValues(typeof(T)).Cast<T>();
#endif
.Where(x => value.Value.HasFlag(x))
.Select(static x => Enum.GetName(typeof(T),x))
.Select(static x => x.ToFirstCharacterLowerCase())));
StringBuilder valueNames = new StringBuilder();
foreach(var x in values)
{
if(value.Value.HasFlag(x) && Enum.GetName(typeof(T), x) is string valueName)
{
if(valueNames.Length > 0)
valueNames.Append(",");
valueNames.Append(valueName.ToFirstCharacterLowerCase());
}
}
WriteStringValue(key, valueNames.ToString());
}
else WriteStringValue(key, value.Value.ToString().ToFirstCharacterLowerCase());
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.Kiota.Serialization.Form.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<PackageProjectUrl>https://aka.ms/kiota/docs</PackageProjectUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<Deterministic>true</Deterministic>
<VersionPrefix>1.2.0</VersionPrefix>
<VersionPrefix>1.2.1</VersionPrefix>
<VersionSuffix></VersionSuffix>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
Expand Down

0 comments on commit 087222f

Please sign in to comment.