| File: RuntimeModel\RuntimeDescription.cs | Web Access |
| Project: src\nuget-client\src\NuGet.Core\NuGet.Packaging\NuGet.Packaging.csproj (NuGet.Packaging) |
// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Collections.Generic; using System.Linq; using NuGet.Shared; namespace NuGet.RuntimeModel { /// <remarks> /// Immutable. /// </remarks> public sealed class RuntimeDescription : IEquatable<RuntimeDescription> { private static readonly IReadOnlyDictionary<string, RuntimeDependencySet> EmptyRuntimeDependencySets = new Dictionary<string, RuntimeDependencySet>(); public string RuntimeIdentifier { get; } public IReadOnlyList<string> InheritedRuntimes { get; } /// <summary> /// RID specific package dependencies, keyed by <see cref="RuntimeDependencySet.Id"/>. /// </summary> public IReadOnlyDictionary<string, RuntimeDependencySet> RuntimeDependencySets { get; } public RuntimeDescription(string runtimeIdentifier) : this(runtimeIdentifier, null, null) { } public RuntimeDescription(string runtimeIdentifier, IEnumerable<string>? inheritedRuntimes) : this(runtimeIdentifier, inheritedRuntimes, null) { } public RuntimeDescription(string runtimeIdentifier, IEnumerable<RuntimeDependencySet>? runtimeDependencySets) : this(runtimeIdentifier, null, runtimeDependencySets) { } public RuntimeDescription(string runtimeIdentifier, IEnumerable<string>? inheritedRuntimes, IEnumerable<RuntimeDependencySet>? runtimeDependencySets) : this( runtimeIdentifier, inheritedRuntimes?.ToList(), runtimeDependencySets?.ToDictionary(d => d.Id, StringComparer.OrdinalIgnoreCase)) { } private RuntimeDescription(string runtimeIdentifier, IReadOnlyList<string>? inheritedRuntimes, IReadOnlyDictionary<string, RuntimeDependencySet>? runtimeDependencySets) { RuntimeIdentifier = runtimeIdentifier; InheritedRuntimes = inheritedRuntimes is null or { Count: 0 } ? Array.Empty<string>() : inheritedRuntimes; RuntimeDependencySets = runtimeDependencySets is null or { Count: 0 } ? EmptyRuntimeDependencySets : runtimeDependencySets; } public bool Equals(RuntimeDescription? other) { if (ReferenceEquals(this, other)) { return true; } if (other == null) { return false; } return string.Equals(other.RuntimeIdentifier, RuntimeIdentifier, StringComparison.Ordinal) && InheritedRuntimes.OrderedEquals(other.InheritedRuntimes, s => s, StringComparer.Ordinal, StringComparer.Ordinal) && RuntimeDependencySets.OrderedEquals(other.RuntimeDependencySets, p => p.Key, StringComparer.OrdinalIgnoreCase); } /// <summary> /// Merges the content of the other runtime description in to this runtime description /// </summary> /// <param name="other">The other description to merge in to this description</param> public static RuntimeDescription Merge(RuntimeDescription left, RuntimeDescription right) { if (!string.Equals(left.RuntimeIdentifier, right.RuntimeIdentifier, StringComparison.Ordinal)) { throw new InvalidOperationException("TODO: Unable to merge runtimes, they do not have the same identifier"); } // Merge #imports List<string> inheritedRuntimes; if (right.InheritedRuntimes.Count != 0 && left.InheritedRuntimes.Count == 0) { // Copy #imports from right inheritedRuntimes = new List<string>(right.InheritedRuntimes); } else { // Ignore the inherited runtimes from the right if there are inherited runtimes on the left. // Copy #imports from left (if any) inheritedRuntimes = new List<string>(left.InheritedRuntimes); } // Merge dependency sets var newSets = new Dictionary<string, RuntimeDependencySet>(StringComparer.OrdinalIgnoreCase); foreach (var dependencySet in left.RuntimeDependencySets.Values) { newSets[dependencySet.Id] = dependencySet; } // Overwrite with things from the right foreach (var dependencySet in right.RuntimeDependencySets.Values) { newSets[dependencySet.Id] = dependencySet; } return new RuntimeDescription( left.RuntimeIdentifier, // If collections are empty, pass null to avoid allocations. inheritedRuntimes.Count == 0 ? null : inheritedRuntimes, newSets.Count == 0 ? null : newSets); } public override bool Equals(object? obj) { return Equals(obj as RuntimeDescription); } public override int GetHashCode() { var combiner = new HashCodeCombiner(); combiner.AddObject(RuntimeIdentifier); combiner.AddSequence(InheritedRuntimes); combiner.AddDictionary(RuntimeDependencySets); return combiner.CombinedHash; } public override string ToString() { return $"({RuntimeIdentifier}: (#imports: {string.Join(",", InheritedRuntimes)}); {string.Join(",", RuntimeDependencySets)})"; } } }