Skip to content

Commit

Permalink
Impl ICollection and IReadOnlyCollection, add more struct enumerators
Browse files Browse the repository at this point in the history
  • Loading branch information
mikernet committed Mar 7, 2024
1 parent 6bd300d commit 868dab4
Show file tree
Hide file tree
Showing 14 changed files with 856 additions and 151 deletions.
41 changes: 39 additions & 2 deletions Source/Singulink.Globalization.Currency/IImmutableMoneySet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Singulink.Globalization;
/// Represents an immutable set of <see cref="Money"/> values.
/// </summary>
[CollectionBuilder(typeof(ImmutableMoneySet), nameof(ImmutableMoneySet.Create))]
public interface IImmutableMoneySet : IReadOnlyMoneySet
public interface IImmutableMoneySet : ICollection<Money>, IReadOnlyMoneySet
{
#if NET7_0_OR_GREATER
/// <summary>
Expand All @@ -18,13 +18,18 @@ public interface IImmutableMoneySet : IReadOnlyMoneySet
public static abstract new IImmutableMoneySet Create(CurrencyRegistry registry, IEnumerable<Money> values);
#endif

/// <summary>
/// Gets the number of values in this set.
/// </summary>
public new int Count { get; }

/// <summary>
/// Adds the specified value to this set and returns the resulting set.
/// </summary>
/// <remarks>
/// Default values that are not associated with any currency are ignored.
/// </remarks>
public IImmutableMoneySet Add(Money value);
public new IImmutableMoneySet Add(Money value);

/// <summary>
/// Adds the specified currency and amount to this set and returns the resulting set.
Expand All @@ -44,6 +49,11 @@ public interface IImmutableMoneySet : IReadOnlyMoneySet
/// </remarks>
public IImmutableMoneySet AddRange(IEnumerable<Money> values);

/// <summary>
/// Returns an empty immutable set that has the same currency registry as this set.
/// </summary>
public new IImmutableMoneySet Clear();

/// <summary>
/// Removes the value with the given currency code and returns the resulting set.
/// </summary>
Expand Down Expand Up @@ -143,4 +153,31 @@ public interface IImmutableMoneySet : IReadOnlyMoneySet
/// Removes all zero amounts from this set and returns the resulting set.
/// </summary>
public IImmutableMoneySet TrimZeroAmounts();

#region Explicit Interface Implementations

/// <summary>
/// Gets a value indicating whether the set is read-only. Always returns <see langword="true"/>.
/// </summary>
bool ICollection<Money>.IsReadOnly => true;

/// <summary>
/// Not supported.
/// </summary>
/// <exception cref="NotSupportedException">This operation is not supported.</exception>
void ICollection<Money>.Add(Money item) => throw new NotSupportedException();

/// <summary>
/// Not supported.
/// </summary>
/// <exception cref="NotSupportedException">This operation is not supported.</exception>
void ICollection<Money>.Clear() => throw new NotSupportedException();

/// <summary>
/// Not supported.
/// </summary>
/// <exception cref="NotSupportedException">This operation is not supported.</exception>
bool ICollection<Money>.Remove(Money item) => throw new NotSupportedException();

#endregion
}
9 changes: 7 additions & 2 deletions Source/Singulink.Globalization.Currency/IMoneySet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Singulink.Globalization;
/// Represents a set of <see cref="Money"/> values.
/// </summary>
[CollectionBuilder(typeof(MoneySetBuilder), nameof(MoneySetBuilder.Create))]
public interface IMoneySet : IReadOnlyMoneySet
public interface IMoneySet : ICollection<Money>, IReadOnlyMoneySet
{
#if NET7_0_OR_GREATER
/// <summary>
Expand All @@ -18,13 +18,18 @@ public interface IMoneySet : IReadOnlyMoneySet
public static abstract new IMoneySet Create(CurrencyRegistry registry, IEnumerable<Money> values);
#endif

/// <summary>
/// Gets the number of values in this set.
/// </summary>
public new int Count { get; }

/// <summary>
/// Adds the specified value to this set.
/// </summary>
/// <remarks>
/// Default values that are not associated with any currency are ignored.
/// </remarks>
public void Add(Money value);
public new void Add(Money value);

/// <summary>
/// Adds the specified currency and amount to this set.
Expand Down
36 changes: 28 additions & 8 deletions Source/Singulink.Globalization.Currency/IReadOnlyMoneySet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Singulink.Globalization;
/// Represents a read-only set of <see cref="Money"/> values.
/// </summary>
[CollectionBuilder(typeof(MoneySetBuilder), nameof(MoneySetBuilder.Create))]
public interface IReadOnlyMoneySet : IEnumerable<Money>, IFormattable
public interface IReadOnlyMoneySet : IReadOnlyCollection<Money>, IFormattable
{
#if NET7_0_OR_GREATER
/// <summary>
Expand All @@ -24,19 +24,14 @@ public interface IReadOnlyMoneySet : IEnumerable<Money>, IFormattable
public Money this[string currencyCode] { get; }

/// <summary>
/// Gets the value this set contains of the given currency. Returns the default money value if it does not contain the currency.
/// Gets the value this set contains of the specified currency. Returns the default money value if it does not contain the currency.
/// </summary>
public Money this[Currency currency] { get; }

/// <summary>
/// Gets the number of values in this set.
/// </summary>
public int Count { get; }

/// <summary>
/// Gets the currencies that this set contains.
/// </summary>
public IEnumerable<Currency> Currencies { get; }
public IReadOnlyCollection<Currency> Currencies { get; }

/// <summary>
/// Gets a value indicating whether this set is sorted by each value's currency code.
Expand All @@ -48,6 +43,31 @@ public interface IReadOnlyMoneySet : IEnumerable<Money>, IFormattable
/// </summary>
CurrencyRegistry Registry { get; }

/// <summary>
/// Determines whether this set contains the specified value.
/// </summary>
public bool Contains(Money value);

/// <summary>
/// Determines whether this set contains the specified amount and currency.
/// </summary>
public bool Contains(decimal amount, Currency currency);

/// <summary>
/// Determines whether this set contains the specified amount and currency code.
/// </summary>
public bool Contains(decimal amount, string currencyCode);

/// <summary>
/// Determines whether this set contains a value with the specified currency.
/// </summary>
public bool ContainsCurrency(Currency currency);

/// <summary>
/// Determines whether this set contains a value with the specified currency code.
/// </summary>
public bool ContainsCurrency(string currencyCode);

/// <summary>
/// Gets the amount associated with the specified currency.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
using System.Collections;
using System.Collections.Immutable;

namespace Singulink.Globalization;

/// <content>
/// Contains the <see cref="CurrencyCollection"/> implementation for <see cref="ImmutableMoneySet"/>.
/// </content>
partial class ImmutableMoneySet
{
/// <summary>
/// Represents a collection of currencies in a <see cref="ImmutableMoneySet"/>.
/// </summary>
public sealed class CurrencyCollection : ICollection<Currency>, IReadOnlyCollection<Currency>
{
private readonly ImmutableMoneySet _set;

internal CurrencyCollection(ImmutableMoneySet set)
{
_set = set;
}

/// <summary>
/// Gets the number of currencies in this collection.
/// </summary>
public int Count => _set.Count;

/// <summary>
/// Determines whether the currency collection contains the specified key.
/// </summary>
public bool Contains(Currency currency) => _set.ContainsCurrency(currency);

/// <summary>
/// Returns an enumerator that iterates through the currencies in this collection.
/// </summary>
public Enumerator GetEnumerator() => new(_set);

#region Explicit Interface Implementations

/// <inheritdoc/>
bool ICollection<Currency>.IsReadOnly => true;

/// <inheritdoc/>
void ICollection<Currency>.CopyTo(Currency[] array, int arrayIndex)
{
CollectionCopy.CheckParams(Count, array, arrayIndex);

foreach (var entry in _set._amountLookup)
array[arrayIndex++] = entry.Key;
}

/// <inheritdoc/>
IEnumerator<Currency> IEnumerable<Currency>.GetEnumerator()
{
throw new NotImplementedException();
}

/// <inheritdoc/>
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}

#endregion

#region Not Supported

/// <summary>
/// Not supported.
/// </summary>
/// <exception cref="NotSupportedException">This operation is not supported.</exception>
void ICollection<Currency>.Clear() => throw new NotSupportedException();

/// <summary>
/// Not supported.
/// </summary>
/// <exception cref="NotSupportedException">This operation is not supported.</exception>
void ICollection<Currency>.Add(Currency item) => throw new NotImplementedException();

/// <summary>
/// Not supported.
/// </summary>
/// <exception cref="NotSupportedException">This operation is not supported.</exception>
bool ICollection<Currency>.Remove(Currency item) => throw new NotImplementedException();

#endregion

/// <summary>
/// Enumerates the elements of a <see cref="CurrencyCollection"/>.
/// </summary>
public struct Enumerator : IEnumerator<Currency>
{
private ImmutableDictionary<Currency, decimal>.Enumerator _entryEnumerator;

internal Enumerator(ImmutableMoneySet set)
{
_entryEnumerator = set._amountLookup.GetEnumerator();
}

/// <summary>
/// Gets the element at the current position of the enumerator.
/// </summary>
public Currency Current => _entryEnumerator.Current.Key;

/// <inheritdoc/>
object? IEnumerator.Current => Current;

/// <summary>
/// Releases all the resources used by the enumerator.
/// </summary>
public void Dispose() => _entryEnumerator.Dispose();

/// <summary>
/// Advances the enumerator to the next element.
/// </summary>
public bool MoveNext() => _entryEnumerator.MoveNext();

/// <summary>
/// Not supported.
/// </summary>
/// <exception cref="NotSupportedException">This operation is not supported.</exception>
void IEnumerator.Reset() => throw new NotSupportedException();
}
}
}
Loading

0 comments on commit 868dab4

Please sign in to comment.