Skip to content

Commit

Permalink
Merge pull request #3453 from microsoft/feature/multi-content-types
Browse files Browse the repository at this point in the history
feature/multi content types
  • Loading branch information
baywet authored Oct 19, 2023
2 parents bcb1492 + 0d54b73 commit f19dec5
Show file tree
Hide file tree
Showing 53 changed files with 1,253 additions and 346 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added support for enum query parameter types. [#2490](https://github.com/microsoft/kiota/issues/2490)
- Added settings in the vscode extension for: backingStore, additionalData, excludeBackwardCompatible, cleanOutput, clearCache, serializers, deserializers, disabledValidationRules, structuredMimeTypes. [#3355](https://github.com/microsoft/kiota/issues/3355)
- Support for primary error message in PHP [#3276](https://github.com/microsoft/kiota/issues/3276)
- Added support for multiple content type request bodies. [#3377](https://github.com/microsoft/kiota/issues/3377)
- Added support for multiple content type responses. [#3377](https://github.com/microsoft/kiota/issues/3377)
- Support for primary error message in Python [#3277](https://github.com/microsoft/kiota/issues/3277)

### Changed
Expand All @@ -23,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fixed a bug where a "models" API path segment in the description would derail generation. [#3400](https://github.com/microsoft/kiota/issues/3400)
- Changes to the configuration of RequestInformation are preserved instead of being overwritten. [#3401](https://github.com/microsoft/kiota/pull/3401).
- Fix bug where import statements in typescript wasn't using import type notation for types that are erased at runtime. [#3190](https://github.com/microsoft/kiota/issues/3190)
- The structured content type generation parameter now supports prioritization with `q=value` syntax. [#3377](https://github.com/microsoft/kiota/issues/3377)

## [1.7.0] - 2023-10-05

Expand Down
10 changes: 5 additions & 5 deletions it/csharp/basic/basic.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Kiota.Abstractions" Version="1.3.0" />
<PackageReference Include="Microsoft.Kiota.Http.HttpClientLibrary" Version="1.0.6" />
<PackageReference Include="Microsoft.Kiota.Abstractions" Version="1.4.0" />
<PackageReference Include="Microsoft.Kiota.Http.HttpClientLibrary" Version="1.1.1" />
<PackageReference Include="Microsoft.Kiota.Serialization.Form" Version="1.0.1" />
<PackageReference Include="Microsoft.Kiota.Serialization.Json" Version="1.0.8" />
<PackageReference Include="Microsoft.kiota.Serialization.Multipart" Version="1.0.0" />
<PackageReference Include="Microsoft.Kiota.Serialization.Text" Version="1.0.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.3" />
<PackageReference Include="xunit" Version="2.5.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.0">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.2" />
<PackageReference Include="xunit" Version="2.5.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Expand Down
17 changes: 9 additions & 8 deletions it/go/basic/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,26 @@ module integrationtest
go 1.20

require (
github.com/microsoft/kiota-abstractions-go v1.2.0
github.com/microsoft/kiota-http-go v0.16.1
github.com/microsoft/kiota-serialization-form-go v0.9.0
github.com/microsoft/kiota-abstractions-go v1.3.0
github.com/microsoft/kiota-http-go v1.1.0
github.com/microsoft/kiota-serialization-form-go v1.0.0
github.com/microsoft/kiota-serialization-json-go v1.0.4
github.com/microsoft/kiota-serialization-multipart-go v1.0.0
github.com/microsoft/kiota-serialization-text-go v0.7.0
github.com/microsoft/kiota-serialization-text-go v1.0.0
)

require (
github.com/cjlapao/common-go v0.0.39 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-logr/logr v1.2.4 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/google/uuid v1.3.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/std-uritemplate/std-uritemplate/go v0.0.42 // indirect
github.com/stretchr/testify v1.8.4 // indirect
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
go.opentelemetry.io/otel v1.16.0 // indirect
go.opentelemetry.io/otel/metric v1.16.0 // indirect
go.opentelemetry.io/otel/trace v1.16.0 // indirect
go.opentelemetry.io/otel v1.19.0 // indirect
go.opentelemetry.io/otel/metric v1.19.0 // indirect
go.opentelemetry.io/otel/trace v1.19.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
18 changes: 18 additions & 0 deletions it/go/basic/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,50 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/microsoft/kiota-abstractions-go v1.2.0 h1:lUriJgqdCY/QajwWQOgTCQE9Atywfe2NHhgoTCSXTRE=
github.com/microsoft/kiota-abstractions-go v1.2.0/go.mod h1:RkxyZ5x87Njik7iVeQY9M2wtrrL1MJZcXiI/BxD/82g=
github.com/microsoft/kiota-abstractions-go v1.3.0 h1:mZTAg+Lf43+hoqTYWT53F/Dg+f0bqtHULnTI/GyiXn8=
github.com/microsoft/kiota-abstractions-go v1.3.0/go.mod h1:yPSuzNSOIVQSFFe1iT+3Lu5zmis22E8Wg+bkyjhd+pY=
github.com/microsoft/kiota-http-go v0.16.1 h1:5SZbSwHs14Xve5VMQHHz00lwL/kEg3H9rgESAUrXnvw=
github.com/microsoft/kiota-http-go v0.16.1/go.mod h1:pKSaeSaBwh3Zadbnzw3kALEZbCZA1gq7A5PuxwVd/aU=
github.com/microsoft/kiota-http-go v1.1.0 h1:L5I93EiNtlP/X6YzeTlhjWt7Q1DxzC9CmWSVtX3b0tE=
github.com/microsoft/kiota-http-go v1.1.0/go.mod h1:zESUM6ovki9LEupqziCbxJ+FAYoF0dFDYZVpOkAfSLc=
github.com/microsoft/kiota-serialization-form-go v0.9.0 h1:ZMyvuxg7z1LmRWJOXr5QuJlwnD/tuNatb+k1KPURBFQ=
github.com/microsoft/kiota-serialization-form-go v0.9.0/go.mod h1:FQqYzIrGX6KUoDOlg+DhDWoGaZoB8AicBYGOsBq0Dw4=
github.com/microsoft/kiota-serialization-form-go v1.0.0 h1:UNdrkMnLFqUCccQZerKjblsyVgifS11b3WCx+eFEsAI=
github.com/microsoft/kiota-serialization-form-go v1.0.0/go.mod h1:h4mQOO6KVTNciMF6azi1J9QB19ujSw3ULKcSNyXXOMA=
github.com/microsoft/kiota-serialization-json-go v1.0.4 h1:5TaISWwd2Me8clrK7SqNATo0tv9seOq59y4I5953egQ=
github.com/microsoft/kiota-serialization-json-go v1.0.4/go.mod h1:rM4+FsAY+9AEpBsBzkFFis+b/LZLlNKKewuLwK9Q6Mg=
github.com/microsoft/kiota-serialization-multipart-go v1.0.0 h1:3O5sb5Zj+moLBiJympbXNaeV07K0d46IfuEd5v9+pBs=
github.com/microsoft/kiota-serialization-multipart-go v1.0.0/go.mod h1:yauLeBTpANk4L03XD985akNysG24SnRJGaveZf+p4so=
github.com/microsoft/kiota-serialization-text-go v0.7.0 h1:uayeq8fpDcZgL0zDyLkYZsH6zNnEXKgp+bRWfR5LcxA=
github.com/microsoft/kiota-serialization-text-go v0.7.0/go.mod h1:2su1PTllHCMNkHugmvpYad+AKBXUUGoiNP3xOAJUL7w=
github.com/microsoft/kiota-serialization-text-go v1.0.0 h1:XOaRhAXy+g8ZVpcq7x7a0jlETWnWrEum0RhmbYrTFnA=
github.com/microsoft/kiota-serialization-text-go v1.0.0/go.mod h1:sM1/C6ecnQ7IquQOGUrUldaO5wj+9+v7G2W3sQ3fy6M=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/std-uritemplate/std-uritemplate/go v0.0.42 h1:rG+XlE4drkVWs2NLfGS15N+vg+CUcjXElQKvJ0fctlI=
github.com/std-uritemplate/std-uritemplate/go v0.0.42/go.mod h1:Qov4Ay4U83j37XjgxMYevGJFLbnZ2o9cEOhGufBKgKY=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4=
github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4=
go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s=
go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4=
go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs=
go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY=
go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo=
go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4=
go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE=
go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8=
go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs=
go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0=
go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg=
go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
Expand Down
2 changes: 1 addition & 1 deletion it/go/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.20
require (
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0
github.com/microsoft/kiota-abstractions-go v1.3.0
github.com/microsoft/kiota-authentication-azure-go v1.0.0
github.com/microsoft/kiota-authentication-azure-go v1.0.1
github.com/microsoft/kiota-http-go v1.1.0
github.com/microsoft/kiota-serialization-form-go v1.0.0
github.com/microsoft/kiota-serialization-json-go v1.0.4
Expand Down
2 changes: 2 additions & 0 deletions it/go/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ github.com/microsoft/kiota-abstractions-go v1.3.0 h1:mZTAg+Lf43+hoqTYWT53F/Dg+f0
github.com/microsoft/kiota-abstractions-go v1.3.0/go.mod h1:yPSuzNSOIVQSFFe1iT+3Lu5zmis22E8Wg+bkyjhd+pY=
github.com/microsoft/kiota-authentication-azure-go v1.0.0 h1:29FNZZ/4nnCOwFcGWlB/sxPvWz487HA2bXH8jR5k2Rk=
github.com/microsoft/kiota-authentication-azure-go v1.0.0/go.mod h1:rnx3PRlkGdXDcA/0lZQTbBwyYGmc+3POt7HpE/e4jGw=
github.com/microsoft/kiota-authentication-azure-go v1.0.1 h1:F4HH+2QQHSecQg50gVEZaUcxA8/XxCaC2oOMYv2gTIM=
github.com/microsoft/kiota-authentication-azure-go v1.0.1/go.mod h1:IbifJeoi+sULI0vjnsWYSmDu5atFo/4FZ6WCoAkPjsc=
github.com/microsoft/kiota-http-go v1.1.0 h1:L5I93EiNtlP/X6YzeTlhjWt7Q1DxzC9CmWSVtX3b0tE=
github.com/microsoft/kiota-http-go v1.1.0/go.mod h1:zESUM6ovki9LEupqziCbxJ+FAYoF0dFDYZVpOkAfSLc=
github.com/microsoft/kiota-serialization-form-go v1.0.0 h1:UNdrkMnLFqUCccQZerKjblsyVgifS11b3WCx+eFEsAI=
Expand Down
15 changes: 11 additions & 4 deletions src/Kiota.Builder/CodeDOM/CodeMethod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Linq;
using Kiota.Builder.Extensions;
using Kiota.Builder.OrderComparers;

namespace Kiota.Builder.CodeDOM;

Expand Down Expand Up @@ -124,9 +125,15 @@ public HttpMethod? HttpMethod
get; set;
}
public string RequestBodyContentType { get; set; } = string.Empty;
#pragma warning disable CA2227
public HashSet<string> AcceptedResponseTypes { get; set; } = new(StringComparer.OrdinalIgnoreCase);
#pragma warning restore CA2227
public IList<string> AcceptedResponseTypes { get; private set; } = new List<string>();
public void AddAcceptedResponsesTypes(IEnumerable<string> types)
{
if (types == null) return;
if (AcceptedResponseTypes is List<string> list)
list.AddRange(types);
}
public bool ShouldAddAcceptHeader => AcceptedResponseTypes.Any();
public string AcceptHeaderValue => string.Join(", ", AcceptedResponseTypes);
public AccessModifier Access { get; set; } = AccessModifier.Public;
#nullable disable // exposing property is required
private CodeTypeBase returnType;
Expand Down Expand Up @@ -302,7 +309,7 @@ public object Clone()
Parent = Parent,
OriginalIndexer = OriginalIndexer,
errorMappings = new(errorMappings),
AcceptedResponseTypes = new(AcceptedResponseTypes, StringComparer.OrdinalIgnoreCase),
AcceptedResponseTypes = new List<string>(AcceptedResponseTypes),
PagingInformation = PagingInformation?.Clone() as PagingInformation,
Documentation = (CodeDocumentation)Documentation.Clone(),
Deprecation = Deprecation,
Expand Down
4 changes: 4 additions & 0 deletions src/Kiota.Builder/CodeDOM/CodeParameter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ public enum CodeParameterKind
/// Configuration for the request to be sent with the headers, query parameters, and middleware options
/// </summary>
RequestConfiguration,
/// <summary>
/// The content type of the request body when it couldn't be inferred from the description.
/// </summary>
RequestBodyContentType,
}

public class CodeParameter : CodeTerminalWithKind<CodeParameterKind>, ICloneable, IDocumentedElement, IDeprecableElement
Expand Down
2 changes: 1 addition & 1 deletion src/Kiota.Builder/CodeRenderers/CodeRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

using Kiota.Builder.CodeDOM;
using Kiota.Builder.Configuration;
using Kiota.Builder.OrderComparers;
using Kiota.Builder.Writers;

namespace Kiota.Builder.CodeRenderers;
Expand Down
1 change: 1 addition & 0 deletions src/Kiota.Builder/CodeRenderers/PythonCodeRenderer.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Kiota.Builder.Configuration;
using Kiota.Builder.OrderComparers;

namespace Kiota.Builder.CodeRenderers;
public class PythonCodeRenderer : CodeRenderer
Expand Down
16 changes: 8 additions & 8 deletions src/Kiota.Builder/Configuration/GenerationConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,14 @@ public bool CleanOutput
{
get; set;
}
public HashSet<string> StructuredMimeTypes
public StructuredMimeTypesCollection StructuredMimeTypes
{
get; set;
} = new(4, StringComparer.OrdinalIgnoreCase) {
"application/json",
"text/plain",
"application/x-www-form-urlencoded",
"multipart/form-data",
} = new StructuredMimeTypesCollection {
"application/json;q=1",
"text/plain;q=0.9",
"application/x-www-form-urlencoded;q=0.2",
"multipart/form-data;q=0.1",
};
public HashSet<string> IncludePatterns { get; set; } = new(0, StringComparer.OrdinalIgnoreCase);
public HashSet<string> ExcludePatterns { get; set; } = new(0, StringComparer.OrdinalIgnoreCase);
Expand All @@ -139,7 +139,7 @@ public object Clone()
Serializers = new(Serializers ?? Enumerable.Empty<string>(), StringComparer.OrdinalIgnoreCase),
Deserializers = new(Deserializers ?? Enumerable.Empty<string>(), StringComparer.OrdinalIgnoreCase),
CleanOutput = CleanOutput,
StructuredMimeTypes = new(StructuredMimeTypes ?? Enumerable.Empty<string>(), StringComparer.OrdinalIgnoreCase),
StructuredMimeTypes = new(StructuredMimeTypes ?? Enumerable.Empty<string>()),
IncludePatterns = new(IncludePatterns ?? Enumerable.Empty<string>(), StringComparer.OrdinalIgnoreCase),
ExcludePatterns = new(ExcludePatterns ?? Enumerable.Empty<string>(), StringComparer.OrdinalIgnoreCase),
ClearCache = ClearCache,
Expand All @@ -164,7 +164,7 @@ internal void UpdateConfigurationFromLanguagesInformation(LanguagesInformation l
if (languageInfo.StructuredMimeTypes.Any() &&
comparer.Equals(StructuredMimeTypes, defaultConfiguration.StructuredMimeTypes) &&
!comparer.Equals(languageInfo.StructuredMimeTypes, StructuredMimeTypes))
StructuredMimeTypes = new(languageInfo.StructuredMimeTypes, StringComparer.OrdinalIgnoreCase);
StructuredMimeTypes = new(languageInfo.StructuredMimeTypes);
}
}
#pragma warning restore CA1056
Expand Down
123 changes: 123 additions & 0 deletions src/Kiota.Builder/Configuration/StructuredMimeTypesCollection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;

namespace Kiota.Builder.Configuration;

public partial class StructuredMimeTypesCollection : ICollection<string>
{
[GeneratedRegex(@"(?<mime>[^;]+);?q?=?(?<priority>[\d.]+)?", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline, 2000)]
private static partial Regex mimeTypesRegex();
private readonly static Regex mimeTypesRegexInstance = mimeTypesRegex();
private readonly Dictionary<string, float> _mimeTypes;

public int Count => _mimeTypes.Count;

public bool IsReadOnly => false;
public StructuredMimeTypesCollection() : this(Array.Empty<string>()) { }
public StructuredMimeTypesCollection(IEnumerable<string> mimeTypes)
{
ArgumentNullException.ThrowIfNull(mimeTypes);
_mimeTypes = mimeTypes.Select(GetKeyAndPriority)
.OfType<KeyValuePair<string, float>>()
.ToDictionary(static x => x.Key, static x => x.Value, StringComparer.OrdinalIgnoreCase);
}
private static KeyValuePair<string, float>? GetKeyAndPriority(string rawFormat)
{
if (string.IsNullOrEmpty(rawFormat))
return null;
var match = mimeTypesRegexInstance.Match(rawFormat);
if (match.Success)
{
var priority = match.Groups["priority"].Success && float.TryParse(match.Groups["priority"].Value, CultureInfo.InvariantCulture, out var resultPriority) ? resultPriority : 1;
return new KeyValuePair<string, float>(match.Groups["mime"].Value, priority);
}
else
{
return null;
}
}
public IEnumerator<string> GetEnumerator()
{
return _mimeTypes.OrderByDescending(static x => x.Value).Select(NormalizeMimeType).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public bool Contains(string item)
{
if (string.IsNullOrEmpty(item))
return false;
return _mimeTypes.ContainsKey(item);
}
public float? GetPriority(string mimeType)
{
if (string.IsNullOrEmpty(mimeType))
return null;
return _mimeTypes.TryGetValue(mimeType, out var priority) ? priority : null;
}

public void Add(string item)
{
if (GetKeyAndPriority(item) is { } result)
_mimeTypes.TryAdd(result.Key, result.Value);
}

public void Clear()
{
_mimeTypes.Clear();
}

/// <inheritdoc/>
public void CopyTo(string[] array, int arrayIndex)
{
_mimeTypes.OrderByDescending(static x => x.Value).Select(NormalizeMimeType).ToArray().CopyTo(array, arrayIndex);
}
private static string NormalizeMimeType(KeyValuePair<string, float> mimeType)
{
return NormalizeMimeType(mimeType.Key, mimeType.Value);
}
private static string NormalizeMimeType(string key, float value)
{
return $"{key};q={value}";
}
///<inheritdoc/>
public bool Remove(string item)
{
if (GetKeyAndPriority(item) is { } result && _mimeTypes.ContainsKey(result.Key))
{
_mimeTypes.Remove(result.Key);
return true;
}
else
return false;
}
public IEnumerable<string> GetAcceptedTypes(IEnumerable<string> searchTypes)
{
ArgumentNullException.ThrowIfNull(searchTypes);
return searchTypes.Select(GetKeyAndPriority)
.OfType<KeyValuePair<string, float>>()
.Select(static x => x.Key)
.Distinct(StringComparer.OrdinalIgnoreCase)
.Select(x => _mimeTypes.TryGetValue(x, out var result) ? NormalizeMimeType(x, result) : null)
.OfType<string>()
.Order(StringComparer.OrdinalIgnoreCase);
}
public IEnumerable<string> GetContentTypes(IEnumerable<string> searchTypes)
{
ArgumentNullException.ThrowIfNull(searchTypes);
return searchTypes.Select(GetKeyAndPriority)
.OfType<KeyValuePair<string, float>>()
.Select(static x => x.Key)
.Distinct(StringComparer.OrdinalIgnoreCase)
.Select(x => _mimeTypes.TryGetValue(x, out var result) ? new KeyValuePair<string, float>?(new(x, result)) : null)
.OfType<KeyValuePair<string, float>>()
.OrderByDescending(static x => x.Value)
.ThenByDescending(static x => x.Key, StringComparer.OrdinalIgnoreCase)
.Select(static x => x.Key);
}
}
Loading

0 comments on commit f19dec5

Please sign in to comment.