public static Await <R> Many <T, R>( Func <Result <T>, int, Optional <R> > choose, R defaultResult, params Await <T>[] sources) { return(complete => { var cancels = Stack <Cancelable> .Empty; var completeFirst = new CompleteFirst(); var completeLast = new CompleteLast(sources.Length); Complete <R> cancelRestAndComplete = result => completeFirst.Do(() => { cancels.ForEach(x => Try.Do(() => x())); complete(result); }); for (var i = 0; i < sources.Length; i++) { var index = i; // save index to use in lambda var current = sources[i](result => { if (result.IsNone) // it means that we ignoring external canceling. { return; } var choice = Try.Do(() => choose(result.Some, index)); if (choice.IsError) { cancelRestAndComplete(Error.Of <R>(choice.Error)); } else if (choice.Success.IsSome) { cancelRestAndComplete(Success.Of(choice.Success.Some)); } else // at last try to complete whole workflow with default result. { completeLast.Do(() => completeFirst.Do(() => complete(Success.Of(defaultResult)))); } }); if (completeFirst.IsCompleted) // if all is done just return { return NothingToCancel; } cancels = cancels.Add(current); } return () => cancelRestAndComplete(None.Of <Result <R> >()); }); }
public static Result <T> Do <T>(Func <T> action, Action <Exception> onError = null) { try { return(Success.Of(action())); } catch (Exception error) { (onError ?? Setup.OnError)(error); return(Error.Of <T>(error)); } }
public static Await <R> Many <T1, T2, R>( Await <T1> source1, Await <T2> source2, R defaultResult, Func <Optional <Result <T1> >, Optional <Result <T2> >, Optional <R> > choose) { var result1 = None.Of <Result <T1> >(); var result2 = None.Of <Result <T2> >(); return(Many( (_, i) => choose(result1, result2), defaultResult, source1.Take(result => result1 = Success.Of(result)), source2.Take(result => result2 = Success.Of(result)))); }
public static Await <R> Map <T, R>(this Await <T> source, Func <T, R> map) { return(complete => source(result => { if (result.IsNone) { complete(None.Of <Result <R> >()); } else if (result.Some.IsError) { complete(Error.Of <R>(result.Some.Error)); } else { var converted = Try.Do(() => map(result.Some.Success)); complete(converted.IsSuccess ? Success.Of(converted.Success) : Error.Of <R>(converted.Error)); } })); }
public static Result <R> Map <T, R>(this Result <T> source, Func <T, R> map) { return(source.Match(x => Success.Of(map(x)), Error.Of <R>)); }
public static Result <T> Of <T>(T success, Exception error) { return(error == null?Success.Of(success) : Error.Of <T>(error)); }