2022-12-23 12:38:51 -05:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
2024-09-05 22:53:48 -04:00
|
|
|
|
using System.Threading;
|
|
|
|
|
using System.Threading.Tasks;
|
2022-12-23 12:38:51 -05:00
|
|
|
|
|
|
|
|
|
namespace FruityFoundation.Base.Structures;
|
2021-11-19 00:12:02 -05:00
|
|
|
|
|
|
|
|
|
public static class MaybeExtensions
|
|
|
|
|
{
|
2022-09-23 21:08:48 -04:00
|
|
|
|
public static Maybe<T> FirstOrEmpty<T>(this IEnumerable<T> collection)
|
|
|
|
|
{
|
|
|
|
|
using var enumerator = collection.GetEnumerator();
|
|
|
|
|
|
2023-08-01 22:12:54 -04:00
|
|
|
|
return !enumerator.MoveNext() ? Maybe.Empty<T>() : enumerator.Current;
|
2022-09-23 21:08:48 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Maybe<T> FirstOrEmpty<T>(this IEnumerable<T> collection, Func<T, bool> pred)
|
|
|
|
|
{
|
|
|
|
|
foreach (var item in collection)
|
|
|
|
|
if (pred(item))
|
|
|
|
|
return item;
|
|
|
|
|
|
2023-08-01 22:12:54 -04:00
|
|
|
|
return Maybe.Empty<T>();
|
2022-09-23 21:08:48 -04:00
|
|
|
|
}
|
2021-11-19 00:12:02 -05:00
|
|
|
|
|
2024-09-05 22:53:48 -04:00
|
|
|
|
public static async ValueTask<Maybe<T>> FirstOrEmptyAsync<T>(this IAsyncEnumerable<T> source, CancellationToken cancellationToken = default)
|
|
|
|
|
{
|
|
|
|
|
if (source is IList<T> { Count: > 0 } list)
|
|
|
|
|
return Maybe.Create(list[0]);
|
|
|
|
|
|
|
|
|
|
await using var e = source
|
|
|
|
|
.ConfigureAwait(false)
|
|
|
|
|
.WithCancellation(cancellationToken)
|
|
|
|
|
.GetAsyncEnumerator();
|
|
|
|
|
|
|
|
|
|
if (await e.MoveNextAsync())
|
|
|
|
|
return e.Current;
|
|
|
|
|
|
|
|
|
|
return Maybe.Empty<T>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static async ValueTask<Maybe<T>> FirstOrEmptyAsync<T>(this IAsyncEnumerable<T> source, Func<T, bool> predicate, CancellationToken cancellationToken = default)
|
|
|
|
|
{
|
|
|
|
|
if (source is IList<T> { Count: > 0 } list)
|
|
|
|
|
return list[0];
|
|
|
|
|
|
|
|
|
|
await using var e = source
|
|
|
|
|
.ConfigureAwait(false)
|
|
|
|
|
.WithCancellation(cancellationToken)
|
|
|
|
|
.GetAsyncEnumerator();
|
|
|
|
|
|
|
|
|
|
while (await e.MoveNextAsync())
|
|
|
|
|
{
|
|
|
|
|
var value = e.Current;
|
|
|
|
|
|
|
|
|
|
if (predicate(value))
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Maybe.Empty<T>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static async ValueTask<Maybe<T>> FirstOrEmptyAsync<T>(this IAsyncEnumerable<T> source, Func<T, ValueTask<bool>> asyncPredicate, CancellationToken cancellationToken = default)
|
|
|
|
|
{
|
|
|
|
|
if (source is IList<T> { Count: > 0 } list)
|
|
|
|
|
return list[0];
|
|
|
|
|
|
|
|
|
|
await using var e = source
|
|
|
|
|
.ConfigureAwait(false)
|
|
|
|
|
.WithCancellation(cancellationToken)
|
|
|
|
|
.GetAsyncEnumerator();
|
|
|
|
|
|
|
|
|
|
while (await e.MoveNextAsync())
|
|
|
|
|
{
|
|
|
|
|
var value = e.Current;
|
|
|
|
|
|
|
|
|
|
if (await asyncPredicate(value).ConfigureAwait(false))
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Maybe.Empty<T>();
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-19 21:43:00 -05:00
|
|
|
|
public static Maybe<TValue> TryGetValue<TKey, TValue>(this IDictionary<TKey, TValue> dict, TKey key) =>
|
2024-04-30 13:18:51 -04:00
|
|
|
|
dict.TryGetValue(key, out var value) ? Maybe.Create(value) : Maybe.Empty<TValue>();
|
2023-08-02 20:26:10 -04:00
|
|
|
|
|
2023-08-01 22:12:54 -04:00
|
|
|
|
public static Maybe<TValue> TryGet<TKey, TValue>(this IReadOnlyDictionary<TKey, TValue> dict, TKey key) =>
|
2024-04-30 13:18:51 -04:00
|
|
|
|
dict.TryGetValue(key, out var value) ? Maybe.Create(value) : Maybe.Empty<TValue>();
|
2023-08-01 22:12:54 -04:00
|
|
|
|
|
2021-11-19 00:12:02 -05:00
|
|
|
|
public static T? ToNullable<T>(this Maybe<T> item) where T : struct =>
|
|
|
|
|
item.HasValue ? item.Value : null;
|
2023-08-01 22:12:54 -04:00
|
|
|
|
}
|