using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Sony.Filtr.Functional { public static class ResultExtensions { public static Result ToResult(this T value) { return Result.Success(value); } public static T Flatten(this Result result) { return result.IsFailed ? throw result.Exception : result.Value; } public static async Task Flatten(this Task> resultTask) { Result result = await resultTask; return result.IsFailed ? throw result.Exception : result.Value; } public static Task> ToTask(this Result result) { return Task.FromResult(result); } public static Result Bind(this Result result, Func> func) { return result.IsOk ? func(result.Value) : Result.FromException(result.Exception); } public static Result BindMany(this Result result, Func func) { if (result.IsFailed) { return Result.FromException(result.Exception); } return result.Value.Select(item => func(item)).ToArray().ToResult(); } public static Result Bind(this Result result, Func func) { return result.Bind(func.TryCatch()); } public static async Task> Bind(this Task> input, Func> f) { var result = await input; if (result.IsOk) { return f(result.Value); } return Result.FromException(result.Exception); } public static async Task> Bind(this Task> input, Func f) { return await input.Bind(f.TryCatch()); } public static async Task> BindAsync(this Result result, Func> func) { if (result.IsFailed) { Result.FromException(result.Exception); } return await func.TryCatch()(result.Value); } public static async Task> BindAsync(this Result result, Func>> func) { if (result.IsFailed) { Result.FromException(result.Exception); } return await func(result.Value); } public static async Task> BindAsync(this Task> input, Func>> f) { var result = await input; if (result.IsOk) { return await f(result.Value); } return Result.FromException(result.Exception); } public static async Task>> BindManyAsync(this Task>> input, Func f) { var result = await input; if (result.IsOk) { return result.Value .Select(v => f(v)) .ToList(); } return Result>.FromException(result.Exception); } public static async Task> BindAsync(this Task> input, Func> f) { return await input.BindAsync(f.TryCatch()); } public static async Task> TapAsync(this Task> resultTask, Action action) { var result = await resultTask; if (result.IsOk) { action(); } return result; } public static async Task> TapAsync(this Task> resultTask, Func action) { var result = await resultTask; if (result.IsOk) { await action(); } return result; } public static async Task> TapAsync(this Task> resultTask, Action action) { var result = await resultTask; if (result.IsOk) { action(result.Value); } return result; } public static async Task> TapAsync(this Task> resultTask, Func action) { var result = await resultTask; if (result.IsOk) { await action(result.Value); } return result; } public static async Task> TapAsync(this Task> resultTask, Func action, Func mapper) { var result = await resultTask; if (result.IsOk) { await action(mapper(result.Value)); } return result; } public static Result Tap(this Result result, Action action) { if (result.IsOk) { action(result.Value); } return result; } public static Result OnFailure(this Result result, Action action) { if (result.IsFailed) { action(result.Exception); } return result; } public static Result OnSuccess(this Result result, Action action) { if (result.IsOk) { action(result.Value); } return result; } } }