| | 1 | | // Copyright (c) ZeroC, Inc. |
| | 2 | |
|
| | 3 | | using System.Collections; |
| | 4 | |
|
| | 5 | | namespace IceRpc.Features; |
| | 6 | |
|
| | 7 | | /// <summary>Default implementation of <see cref="IFeatureCollection" />.</summary> |
| | 8 | | public class FeatureCollection : IFeatureCollection |
| | 9 | | { |
| | 10 | | /// <summary>Gets a shared empty read-only instance.</summary> |
| | 11 | | /// <value>An empty <see cref="FeatureCollection" />.</value> |
| 11731 | 12 | | public static IFeatureCollection Empty { get; } = new FeatureCollection().AsReadOnly(); |
| | 13 | |
|
| | 14 | | /// <summary>Gets a value indicating whether this feature collection is read-only or read-write.</summary> |
| | 15 | | /// <value>Always <see langword="false" /> with this class.</value> |
| 150 | 16 | | public bool IsReadOnly => false; |
| | 17 | |
|
| | 18 | | private readonly IFeatureCollection? _defaults; |
| 228 | 19 | | private readonly Dictionary<Type, object> _features = new(); |
| | 20 | |
|
| | 21 | | /// <inheritdoc/> |
| | 22 | | public object? this[Type key] |
| | 23 | | { |
| 909 | 24 | | get => _features.TryGetValue(key, out object? value) ? value : _defaults?[key]; |
| | 25 | |
|
| | 26 | | set |
| 322 | 27 | | { |
| 322 | 28 | | if (value is null) |
| 3 | 29 | | { |
| 3 | 30 | | _ = _features.Remove(key); |
| 3 | 31 | | } |
| | 32 | | else |
| 319 | 33 | | { |
| 319 | 34 | | _features[key] = value; |
| 319 | 35 | | } |
| 322 | 36 | | } |
| | 37 | | } |
| | 38 | |
|
| | 39 | | /// <summary>Constructs an empty read-write feature collection.</summary> |
| 43 | 40 | | public FeatureCollection() |
| 43 | 41 | | { |
| 43 | 42 | | } |
| | 43 | |
|
| | 44 | | /// <summary>Constructs an empty read-write feature collection with defaults.</summary> |
| | 45 | | /// <param name="defaults">The feature collection that provide default values.</param> |
| 185 | 46 | | public FeatureCollection(IFeatureCollection defaults) => |
| | 47 | | // no need to query the empty read-only collection for defaults; any other feature collection (even empty and |
| | 48 | | // read-only) can change over time |
| 185 | 49 | | _defaults = defaults == Empty ? null : defaults; |
| | 50 | |
|
| | 51 | | /// <inheritdoc/> |
| 905 | 52 | | public TFeature? Get<TFeature>() => this[typeof(TFeature)] is object value ? (TFeature)value : default; |
| | 53 | |
|
| | 54 | | /// <inheritdoc /> |
| 0 | 55 | | IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); |
| | 56 | |
|
| | 57 | | /// <summary>Returns an enumerator that iterates over this feature collection.</summary> |
| | 58 | | /// <returns>An <see cref="IEnumerator{T}"/> object that can be used to iterate through this feature collection. |
| | 59 | | /// </returns> |
| | 60 | | public IEnumerator<KeyValuePair<Type, object>> GetEnumerator() |
| 10 | 61 | | { |
| 50 | 62 | | foreach (KeyValuePair<Type, object> pair in _features) |
| 10 | 63 | | { |
| 10 | 64 | | yield return pair; |
| 10 | 65 | | } |
| | 66 | |
|
| 10 | 67 | | if (_defaults is not null) |
| 6 | 68 | | { |
| 42 | 69 | | foreach (KeyValuePair<Type, object> pair in _defaults) |
| 12 | 70 | | { |
| 12 | 71 | | if (!_features.ContainsKey(pair.Key)) |
| 8 | 72 | | { |
| 8 | 73 | | yield return pair; |
| 8 | 74 | | } |
| 12 | 75 | | } |
| 6 | 76 | | } |
| 10 | 77 | | } |
| | 78 | |
|
| | 79 | | /// <inheritdoc/> |
| 310 | 80 | | public void Set<TFeature>(TFeature? feature) => this[typeof(TFeature)] = feature; |
| | 81 | | } |