mirror of
https://github.com/nsnail/spectre.console.git
synced 2025-07-01 18:38:16 +08:00
Move Spectre.Console.Cli to it's own package
This commit is contained in:

committed by
Patrik Svensson

parent
b600832e00
commit
36ca22ffac
13
src/Spectre.Console.Cli/Internal/Collections/IMultiMap.cs
Normal file
13
src/Spectre.Console.Cli/Internal/Collections/IMultiMap.cs
Normal file
@ -0,0 +1,13 @@
|
||||
namespace Spectre.Console.Cli;
|
||||
|
||||
/// <summary>
|
||||
/// Representation of a multi map.
|
||||
/// </summary>
|
||||
internal interface IMultiMap
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds a key and a value to the multi map.
|
||||
/// </summary>
|
||||
/// <param name="pair">The pair to add.</param>
|
||||
void Add((object? Key, object? Value) pair);
|
||||
}
|
168
src/Spectre.Console.Cli/Internal/Collections/MultiMap.cs
Normal file
168
src/Spectre.Console.Cli/Internal/Collections/MultiMap.cs
Normal file
@ -0,0 +1,168 @@
|
||||
namespace Spectre.Console.Cli;
|
||||
|
||||
[SuppressMessage("Performance", "CA1812: Avoid uninstantiated internal classes")]
|
||||
internal sealed class MultiMap<TKey, TValue> : IMultiMap, ILookup<TKey, TValue>, IDictionary<TKey, TValue>, IReadOnlyDictionary<TKey, TValue>
|
||||
where TKey : notnull
|
||||
{
|
||||
private readonly IDictionary<TKey, MultiMapGrouping> _lookup;
|
||||
private readonly IDictionary<TKey, TValue> _dictionary;
|
||||
|
||||
public int Count => _lookup.Count;
|
||||
|
||||
public bool IsReadOnly => false;
|
||||
|
||||
public ICollection<TKey> Keys => _lookup.Keys;
|
||||
|
||||
public ICollection<TValue> Values => _dictionary.Values;
|
||||
|
||||
IEnumerable<TKey> IReadOnlyDictionary<TKey, TValue>.Keys => _lookup.Keys;
|
||||
|
||||
IEnumerable<TValue> IReadOnlyDictionary<TKey, TValue>.Values => _dictionary.Values;
|
||||
|
||||
TValue IReadOnlyDictionary<TKey, TValue>.this[TKey key] => _dictionary[key];
|
||||
|
||||
TValue IDictionary<TKey, TValue>.this[TKey key]
|
||||
{
|
||||
get
|
||||
{
|
||||
return _dictionary[key];
|
||||
}
|
||||
set
|
||||
{
|
||||
Add(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<TValue> this[TKey key]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_lookup.TryGetValue(key, out var group))
|
||||
{
|
||||
return group;
|
||||
}
|
||||
|
||||
return Array.Empty<TValue>();
|
||||
}
|
||||
}
|
||||
|
||||
public MultiMap()
|
||||
{
|
||||
_lookup = new Dictionary<TKey, MultiMapGrouping>();
|
||||
_dictionary = new Dictionary<TKey, TValue>();
|
||||
}
|
||||
|
||||
private sealed class MultiMapGrouping : IGrouping<TKey, TValue>
|
||||
{
|
||||
private readonly List<TValue> _items;
|
||||
|
||||
public TKey Key { get; }
|
||||
|
||||
public MultiMapGrouping(TKey key, List<TValue> items)
|
||||
{
|
||||
Key = key;
|
||||
_items = items;
|
||||
}
|
||||
|
||||
public void Add(TValue value)
|
||||
{
|
||||
_items.Add(value);
|
||||
}
|
||||
|
||||
public IEnumerator<TValue> GetEnumerator()
|
||||
{
|
||||
return _items.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
}
|
||||
|
||||
public bool Contains(TKey key)
|
||||
{
|
||||
return _lookup.ContainsKey(key);
|
||||
}
|
||||
|
||||
public IEnumerator<IGrouping<TKey, TValue>> GetEnumerator()
|
||||
{
|
||||
foreach (var group in _lookup.Values)
|
||||
{
|
||||
yield return group;
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public void Add(TKey key, TValue value)
|
||||
{
|
||||
if (!_lookup.ContainsKey(key))
|
||||
{
|
||||
_lookup[key] = new MultiMapGrouping(key, new List<TValue>());
|
||||
}
|
||||
|
||||
_lookup[key].Add(value);
|
||||
_dictionary[key] = value;
|
||||
}
|
||||
|
||||
public bool ContainsKey(TKey key)
|
||||
{
|
||||
return Contains(key);
|
||||
}
|
||||
|
||||
public bool Remove(TKey key)
|
||||
{
|
||||
return _lookup.Remove(key);
|
||||
}
|
||||
|
||||
public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value)
|
||||
{
|
||||
return _dictionary.TryGetValue(key, out value);
|
||||
}
|
||||
|
||||
public void Add(KeyValuePair<TKey, TValue> item)
|
||||
{
|
||||
Add(item.Key, item.Value);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_lookup.Clear();
|
||||
}
|
||||
|
||||
public bool Contains(KeyValuePair<TKey, TValue> item)
|
||||
{
|
||||
return Contains(item.Key);
|
||||
}
|
||||
|
||||
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
|
||||
{
|
||||
_dictionary.CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
public bool Remove(KeyValuePair<TKey, TValue> item)
|
||||
{
|
||||
return Remove(item.Key);
|
||||
}
|
||||
|
||||
IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator()
|
||||
{
|
||||
return _dictionary.GetEnumerator();
|
||||
}
|
||||
|
||||
public void Add((object? Key, object? Value) pair)
|
||||
{
|
||||
if (pair.Key != null)
|
||||
{
|
||||
#pragma warning disable CS8604 // Possible null reference argument of value.
|
||||
#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type.
|
||||
Add((TKey)pair.Key, (TValue)pair.Value);
|
||||
#pragma warning restore CS8600 // Converting null literal or possible null value to non-nullable type.
|
||||
#pragma warning restore CS8604 // Possible null reference argument of value.
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user