using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; namespace FruityFoundation.Base.Structures; public static class MaybeExtensions { public static Maybe FirstOrEmpty(this IEnumerable collection) { using var enumerator = collection.GetEnumerator(); return !enumerator.MoveNext() ? Maybe.Empty() : enumerator.Current; } public static Maybe FirstOrEmpty(this IEnumerable collection, Func pred) { foreach (var item in collection) if (pred(item)) return item; return Maybe.Empty(); } public static async ValueTask> FirstOrEmptyAsync(this IAsyncEnumerable source, CancellationToken cancellationToken = default) { if (source is IList { 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(); } public static async ValueTask> FirstOrEmptyAsync(this IAsyncEnumerable source, Func predicate, CancellationToken cancellationToken = default) { if (source is IList { 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(); } public static async ValueTask> FirstOrEmptyAsync(this IAsyncEnumerable source, Func> asyncPredicate, CancellationToken cancellationToken = default) { if (source is IList { 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(); } public static Maybe TryGetValue(this IDictionary dict, TKey key) => dict.TryGetValue(key, out var value) ? Maybe.Create(value) : Maybe.Empty(); public static Maybe TryGet(this IReadOnlyDictionary dict, TKey key) => dict.TryGetValue(key, out var value) ? Maybe.Create(value) : Maybe.Empty(); public static T? ToNullable(this Maybe item) where T : struct => item.HasValue ? item.Value : null; }