using System.Diagnostics; namespace SJK.Functional; public static class OptionExtensions { public static IEnumerable Match(this IEnumerable> values, Func onSome, Func onNone) { foreach (var item in values) { yield return item.Match(onSome, onNone); } } // public static IOption GetValue(this IDictionary value, Tkey key) where Tkey : notnull // { // if (value.TryGetValue(key, out var v)) // { // return v.ToOption(); // } // return None.Of(); // } public static IOption GetValue(this IReadOnlyDictionary value, Tkey key) where Tkey : notnull { if (value.TryGetValue(key, out var v)) { return v.ToOption(); } return None.Of(); } public static IOption OrElse(this IOption option, Func> fallback) { return option.Match( some => option, () => fallback() ); } public static IOption BindUsing( this IOption option, Func> func) where TDisposable : IDisposable { return option.Match( some => { using (some) return func(some); }, () => None.Of() ); } public static IOption ToOption(this T? value) => value != null ? Some.Of(value) : None.Of(); [StackTraceHidden] // [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T OrThrow(this IOption option, Func exceptionFactory) where TEx : Exception { if (option.HasValue(out var value)) return value; throw exceptionFactory(); } public static IEither ToEither(this Tvalue value, Func isSuccess, Func ok, Func err) { return isSuccess(value) ? new Right(ok()) : new Left(err(value)); } public static IEither ToEither(this Tvalue value, Tvalue successValue, Func ok, Func err) { return value.ToEither(e => e.Equals(successValue), ok, err); } // public static IEnumerable> ToOptions(this IEnumerable value) => value.Select(thing => thing.ToOption()); public static Some ToSome(this T value) where T : notnull => Some.Of(value); public static void IfSome(this IOption value, Action onSome) => value.Match(onSome, () => { }); public static void IfNone(this IOption value, Action onNone) => value.Match(_ => { }, onNone); public static T Or(this IOption value, Func @default) => value.Or(@default()); public static IEnumerable OnlySomes(this IEnumerable> options) { foreach (var item in options) { if (item.HasValue(out var item2)) yield return item2; } } // public static None ToNone(this T value) => None.Of(); public static Option ToStructOption(this IOption option) => option.HasValue(out var value) ? Option.Some(value) : Option.None; public static IOption ToClassOption(this Option option) => option.HasValue ? option.Value.ToOption() : None.Of(); }