private static Result <HttpWebResponse, Failed> ValidateResponse(HttpWebResponse response) { Func <HttpWebResponse, Result <HttpWebResponse, Failed> > notFound = wr => wr.StatusCode == HttpStatusCode.NotFound ? Result <HttpWebResponse, Failed> .NewFailure(new NotFound()) : Result <HttpWebResponse, Failed> .NewSuccess(wr); Func <HttpWebResponse, Result <HttpWebResponse, Failed> > redirect = wr => wr.StatusCode == HttpStatusCode.Redirect || wr.StatusCode == HttpStatusCode.TemporaryRedirect ? Result <HttpWebResponse, Failed> .NewFailure( new Moved(new Uri(response.Headers[HttpResponseHeader.Location]))) : Result <HttpWebResponse, Failed> .NewSuccess(wr); Func <HttpWebResponse, Result <HttpWebResponse, Failed> > otherError = wr => wr.StatusCode != HttpStatusCode.OK ? Result <HttpWebResponse, Failed> .NewFailure(new Failed()) : Result <HttpWebResponse, Failed> .NewSuccess(wr); Func <HttpWebResponse, HttpWebResponse, HttpWebResponse> successF = (wr, _) => wr; Func <Failed, Failed, Failed> failedF = (f1, f2) => new Faileds(new[] { f1, f2 }); var valdationF = ResultExtentions.PlusR(successF, failedF, ResultExtentions.PlusR(successF, failedF, notFound, redirect), otherError); return(valdationF(response)); }
private static Result <Resource, Failed> Usecase(Uri address) { var fetchR = ResultExtentions.TryCatchR <Uri, HttpWebResponse, Failed>(Fetch, ExceptionsHandler); var validatedFetchR = fetchR .Compose(ResultExtentions.BindR <HttpWebResponse, HttpWebResponse, Failed>(ValidateResponse)) .ComposeR(Execute); return(validatedFetchR(address)); }
public void PlusR_should_add_success_and_failures() { Func <int, int, int> addSuccess = (a, b) => a; Func <string, string, string> addFailure = (s1, s2) => string.Concat(s1, ", ", s2); Func <int, Result <int, string> > f1 = i => i >= 5 ? Result <int, string> .NewSuccess(i) : Result <int, string> .NewFailure($"value was less than than 5. It was {i}"); Func <int, Result <int, string> > f2 = i => i <= 10 ? Result <int, string> .NewSuccess(i) : Result <int, string> .NewFailure($"value was greater than 10. It was {i}"); Func <int, Result <int, string> > f3 = i => i >= 3 ? Result <int, string> .NewSuccess(i) : Result <int, string> .NewFailure($"value was less than 3. It was {i}"); var plusF1F2 = ResultExtentions.PlusR(addSuccess, addFailure, f1, f2); var plusF1F2F3 = ResultExtentions.PlusR(addSuccess, addFailure, plusF1F2, f3); var inputS = 5; var expectedS = Result <int, string> .NewSuccess(5); var actualS = plusF1F2F3(inputS); Assert.Equal(expectedS, actualS); //----------------------------------------------------------------------------------------- var inputF = 2; var expectedF = Result <int, string> .NewFailure( $"value was less than than 5. It was 2, value was less than 3. It was 2"); var actualF = plusF1F2F3(inputF); Assert.Equal(expectedF, actualF); }
public void DoubleMapR_should_map_success_and_failure() { Func <int, string> fSuccess = i => $"value was {i}"; Func <string, string> fError = e => $"Error was {e}"; var doubleMappedF = ResultExtentions.DoubleMapR(fSuccess, fError); var inputS = Result <int, string> .NewSuccess(2); var expectedS = Result <string, string> .NewSuccess("value was 2"); var actualS = doubleMappedF(inputS); Assert.Equal(expectedS, actualS); //------------------------------------------------------------------------- var inputF = Result <int, string> .NewFailure("some error"); var expectedF = Result <string, string> .NewFailure("Error was some error"); var actualF = doubleMappedF(inputF); Assert.Equal(expectedF, actualF); }
public void Usecase() { Func <Request, Result <Request, string> > validate1 = r => r.Name == "" ? Result <Request, string> .NewFailure("Name must not be blank") : Result <Request, string> .NewSuccess(r); Func <Request, Result <Request, string> > validate2 = r => r.Name.Length > 50 ? Result <Request, string> .NewFailure("Name must not be longer than 50 chars") : Result <Request, string> .NewSuccess(r); Func <Request, Result <Request, string> > validate3 = r => r.Email == "" ? Result <Request, string> .NewFailure("Email must not be blank") : Result <Request, string> .NewSuccess(r); Func <Result <Request, string>, Result <Request, string> > log = twoTrackInput => { Func <Request, Request> success = x => { Debug.WriteLine($"DEBUG. Success so far: {x}"); return(x); }; Func <string, string> failure = x => { Debug.WriteLine($"ERROR. {x}"); return(x); }; return(ResultExtentions.DoubleMapR(success, failure)(twoTrackInput)); }; Func <Request, Result <Request, string> > combinedValidation = r => { Func <Request, Request, Request> addSuccess = (r1, _) => r1; Func <string, string, string> addFailure = (s1, s2) => s1 + "; " + s2; var f1 = ResultExtentions.PlusR(addSuccess, addFailure, validate1, validate2); var resultF = ResultExtentions.PlusR(addSuccess, addFailure, f1, validate3); return(resultF(r)); }; Func <Request, Request> canonicalizeEmail = r => new Request(r.Name, r.Email.Trim().ToLower()); Action <Request> updateDatabase = r => { }; Func <Exception, string> exHandler = e => e.Message; Func <Request, Result <Request, string> > usecase = r => { var resultF = combinedValidation .ComposeR(canonicalizeEmail.SwitchR <Request, Request, string>()) .ComposeR(updateDatabase.Tee().TryCatchR(exHandler)) .Compose(log); return(resultF(r)); }; var goodInput = new Request("Alice", "good"); var badInput = new Request("", ""); var badResult = usecase(badInput); Debug.WriteLine($"Bad Result = {badResult}"); var goodRestul = usecase(goodInput); Debug.WriteLine($"Good Result = {goodRestul}"); }