// Copyright (c) The Geekeey Authors // SPDX-License-Identifier: EUPL-1.2 using System.Diagnostics.Contracts; namespace Geekeey.Request.Result; public partial class Result { /// /// Maps the success value of the result using a mapping function, or does nothing if the result is a failure. /// /// The function used to map the success value. /// The type of the new value. /// A new result containing either the mapped success value or the failure value of the original /// result. [Pure] public Result Map(Func func) { return IsSuccess ? new Result(func(Value)) : new Result(Error); } /// /// Tries to map the success value of the result using a mapping function, or does nothing if the result is a /// failure. If the mapping function throws an exception, the exception will be returned wrapped in an /// . /// /// The function used to map the success value. /// The type of the new value. /// A new result containing either the mapped value, the exception thrown by /// wrapped in an , or the failure value of the original result. [Pure] public Result TryMap(Func func) { try { return Map(func); } catch (Exception exception) { return new Result(new ExceptionError(exception)); } } /// /// Maps the success value of the result to a new result using a mapping function, or does nothing if the result is /// a failure. /// /// The function used to map the success value to a new result. /// The type of the new value. /// A result which is either the mapped result or a new result containing the failure value of the original /// result. [Pure] public Result Then(Func> func) { return IsSuccess ? func(Value) : new Result(Error); } /// /// Tries to map the success value of the result to a new result using a mapping function, or does nothing if the result /// is a failure. If the mapping function throws an exception, the exception will be returned wrapped in an /// . /// /// The function used to map the success value to a new result. /// The type of the new value. /// A result which is either the mapped result, the exception thrown by wrapped in /// an , or a new result containing the failure value of the original result. [Pure] public Result ThenTry(Func> func) { try { return Then(func); } catch (Exception exception) { return new Result(new ExceptionError(exception)); } } } public partial class Result { /// /// Maps the success value of the result using an asynchronous mapping function, or does nothing if the result is /// a failure. /// /// The function used to map the success value. /// The type of the new value. /// A which either completes asynchronously by invoking the mapping function on /// the success value of the result and constructing a new result containing the mapped value, or completes /// synchronously by returning a new result containing the failure value of the original result. [Pure] public Task> MapAsync(Func> func) { if (!IsSuccess) { return Task.FromResult(new Result(Error)); } var task = func(Value); return CreateResult(task); static async Task> CreateResult(Task task) { var value = await task; return new Result(value); } } /// /// Maps the success value of the result using an asynchronous mapping function, or does nothing if the result is a /// failure. If the mapping function throws an exception, the exception will be returned wrapped in an /// . /// /// The function used to map the success value. /// The type of the new value. /// A which either completes asynchronously by invoking the mapping function on /// the success value of the result and constructing a new result containing the mapped value, returning any exception /// thrown by wrapped in an or completes synchronously by /// returning a new result containing the failure value of the original result. [Pure] public Task> TryMapAsync(Func> func) { if (!IsSuccess) { return Task.FromResult(new Result(Error)); } try { var task = func(Value); return CreateResult(task); } catch (Exception exception) { return Task.FromResult(new Result(new ExceptionError(exception))); } static async Task> CreateResult(Task task) { try { var value = await task; return new Result(value); } catch (Exception exception) { return new Result(new ExceptionError(exception)); } } } /// /// Maps the success value of the result to a new result using an asynchronous mapping function, or does nothing if /// the result is a failure. /// /// The function used to map the success value to a new result. /// The type of the new value. /// A which either completes asynchronously by invoking the mapping function on /// the success value of the result, or completes synchronously by returning a new result containing the failure /// value of the original result. [Pure] public Task> ThenAsync(Func>> func) { if (!IsSuccess) { return Task.FromResult(new Result(Error)); } var task = func(Value); return CreateResult(task); static async Task> CreateResult(Task> task) { var result = await task; return result; } } /// /// Maps the success value of the result to a new result using an asynchronous mapping function, or does nothing if /// the result is a failure. If the mapping function throws an exception, the exception will be returned wrapped in /// an . /// /// The function used to map the success value to a new result. /// The type of the new value. /// A which either completes asynchronously by invoking the mapping function on /// the success value of the result, returning any exception thrown by wrapped in an /// , or completes synchronously by returning a new result containing the failure value /// of the original result. [Pure] public Task> ThenTryAsync(Func>> func) { if (!IsSuccess) { return Task.FromResult(new Result(Error)); } try { var task = func(Value); return CreateResult(task); } catch (Exception exception) { return Task.FromResult(new Result(new ExceptionError(exception))); } static async Task> CreateResult(Task> task) { try { var value = await task; return value; } catch (Exception exception) { return new Result(new ExceptionError(exception)); } } } } public partial class Result { /// /// Maps the success value of the result using an asynchronous mapping function, or does nothing if the result is /// a failure. /// /// The function used to map the success value. /// The type of the new value. /// A which either completes asynchronously by invoking the mapping function on /// the success value of the result and constructing a new result containing the mapped value, or completes /// synchronously by returning a new result containing the failure value of the original result. [Pure] public ValueTask> MapAsync(Func> func) { if (!IsSuccess) { return ValueTask.FromResult(new Result(Error)); } var task = func(Value); return CreateResult(task); static async ValueTask> CreateResult(ValueTask task) { var value = await task; return new Result(value); } } /// /// Maps the success value of the result using an asynchronous mapping function, or does nothing if the result is a /// failure. If the mapping function throws an exception, the exception will be returned wrapped in an /// . /// /// The function used to map the success value. /// The type of the new value. /// A which either completes asynchronously by invoking the mapping function on /// the success value of the result and constructing a new result containing the mapped value, returning any exception /// thrown by wrapped in an or completes synchronously by /// returning a new result containing the failure value of the original result. [Pure] public ValueTask> TryMapAsync(Func> func) { if (!IsSuccess) { return ValueTask.FromResult(new Result(Error)); } try { var task = func(Value); return CreateResult(task); } catch (Exception exception) { return ValueTask.FromResult(new Result(new ExceptionError(exception))); } static async ValueTask> CreateResult(ValueTask task) { try { var value = await task; return new Result(value); } catch (Exception exception) { return new Result(new ExceptionError(exception)); } } } /// /// Maps the success value of the result to a new result using an asynchronous mapping function, or does nothing if /// the result is a failure. /// /// The function used to map the success value to a new result. /// The type of the new value. /// A which either completes asynchronously by invoking the mapping function on /// the success value of the result, or completes synchronously by returning a new result containing the failure /// value of the original result. [Pure] public ValueTask> ThenAsync(Func>> func) { if (!IsSuccess) { return ValueTask.FromResult(new Result(Error)); } var task = func(Value); return CreateResult(task); static async ValueTask> CreateResult(ValueTask> task) { var result = await task; return result; } } /// /// Maps the success value of the result to a new result using an asynchronous mapping function, or does nothing if /// the result is a failure. If the mapping function throws an exception, the exception will be returned wrapped in /// an . /// /// The function used to map the success value to a new result. /// The type of the new value. /// A which either completes asynchronously by invoking the mapping function on /// the success value of the result, returning any exception thrown by wrapped in an /// , or completes synchronously by returning a new result containing the failure value /// of the original result. [Pure] public ValueTask> ThenTryAsync(Func>> func) { if (!IsSuccess) { return ValueTask.FromResult(new Result(Error)); } try { var task = func(Value); return CreateResult(task); } catch (Exception exception) { return ValueTask.FromResult(new Result(new ExceptionError(exception))); } static async ValueTask> CreateResult(ValueTask> task) { try { var value = await task; return value; } catch (Exception exception) { return new Result(new ExceptionError(exception)); } } } } public partial class Result { /// /// Chains a non-generic result to this result if it is a success, or does nothing if the result is a failure. /// /// The function used to create the next result. /// A result which is either the mapped result or a new result containing the failure value of the original /// result. [Pure] public Result Then(Func func) { return IsSuccess ? func(Value) : new Result(Error); } /// /// Tries to chain a non-generic result to this result if it is a success, or does nothing if the result is a /// failure. If the function throws an exception, the exception will be returned wrapped in an /// . /// /// The function used to create the next result. /// A result which is either the mapped result, the exception thrown by wrapped in /// an , or a new result containing the failure value of the original result. [Pure] public Result ThenTry(Func func) { try { return Then(func); } catch (Exception exception) { return new Result(new ExceptionError(exception)); } } } public partial class Result { /// /// Chains a non-generic result to this result using an asynchronous mapping function, or does nothing if the result is /// a failure. /// /// The function used to create the next result. /// A which either completes asynchronously by invoking the mapping function, or /// completes synchronously by returning a new result containing the failure value of the original result. [Pure] public Task ThenAsync(Func> func) { if (!IsSuccess) { return Task.FromResult(new Result(Error)); } var task = func(Value); return CreateResult(task); static async Task CreateResult(Task task) { var result = await task; return result; } } /// /// Tries to chain a non-generic result to this result using an asynchronous mapping function, or does nothing if the /// result is a failure. If the mapping function throws an exception, the exception will be returned wrapped in /// an . /// /// The function used to create the next result. /// A which either completes asynchronously by invoking the mapping function, /// returning any exception thrown by wrapped in an , or /// completes synchronously by returning a new result containing the failure value of the original result. [Pure] public Task ThenTryAsync(Func> func) { if (!IsSuccess) { return Task.FromResult(new Result(Error)); } try { var task = func(Value); return CreateResult(task); } catch (Exception exception) { return Task.FromResult(new Result(new ExceptionError(exception))); } static async Task CreateResult(Task task) { try { var value = await task; return value; } catch (Exception exception) { return new Result(new ExceptionError(exception)); } } } } public partial class Result { /// /// Chains a non-generic result to this result using an asynchronous mapping function, or does nothing if the result is /// a failure. /// /// The function used to create the next result. /// A which either completes asynchronously by invoking the mapping function, or /// completes synchronously by returning a new result containing the failure value of the original result. [Pure] public ValueTask ThenAsync(Func> func) { if (!IsSuccess) { return ValueTask.FromResult(new Result(Error)); } var task = func(Value); return CreateResult(task); static async ValueTask CreateResult(ValueTask task) { var result = await task; return result; } } /// /// Tries to chain a non-generic result to this result using an asynchronous mapping function, or does nothing if the /// result is a failure. If the mapping function throws an exception, the exception will be returned wrapped in /// an . /// /// The function used to create the next result. /// A which either completes asynchronously by invoking the mapping function, /// returning any exception thrown by wrapped in an , or /// completes synchronously by returning a new result containing the failure value of the original result. [Pure] public ValueTask ThenTryAsync(Func> func) { if (!IsSuccess) { return ValueTask.FromResult(new Result(Error)); } try { var task = func(Value); return CreateResult(task); } catch (Exception exception) { return ValueTask.FromResult(new Result(new ExceptionError(exception))); } static async ValueTask CreateResult(ValueTask task) { try { var value = await task; return value; } catch (Exception exception) { return new Result(new ExceptionError(exception)); } } } } public partial class Result { /// /// Maps the success of the result to a new success value using a mapping function, or does nothing if the result is /// a failure. /// /// The function used to map the success to a new value. /// The type of the new value. /// A new result containing either the mapped success value or the failure value of the original /// result. [Pure] public Result Map(Func func) { return IsSuccess ? new Result(func()) : new Result(Error); } /// /// Tries to map the success of the result to a new success value using a mapping function, or does nothing if the /// result is a failure. If the mapping function throws an exception, the exception will be returned wrapped in an /// . /// /// The function used to map the success to a new value. /// The type of the new value. /// A new result containing either the mapped value, the exception thrown by /// wrapped in an , or the failure value of the original result. [Pure] public Result TryMap(Func func) { try { return Map(func); } catch (Exception exception) { return new Result(new ExceptionError(exception)); } } /// /// Chains another result to this result if it is a success, or does nothing if the result is a failure. /// /// The function used to create the next result. /// A result which is either the mapped result or a new result containing the failure value of the original /// result. [Pure] public Result Then(Func func) { return IsSuccess ? func() : new Result(Error); } /// /// Tries to chain another result to this result if it is a success, or does nothing if the result is a failure. If /// the function throws an exception, the exception will be returned wrapped in an . /// /// The function used to create the next result. /// A result which is either the mapped result, the exception thrown by wrapped in /// an , or a new result containing the failure value of the original result. [Pure] public Result ThenTry(Func func) { try { return Then(func); } catch (Exception exception) { return new Result(new ExceptionError(exception)); } } /// /// Chains a generic result to this result if it is a success, or does nothing if the result is a failure. /// /// The function used to create the next generic result. /// The type of the new value. /// A result which is either the mapped result or a new result containing the failure value of the original /// result. [Pure] public Result Then(Func> func) { return IsSuccess ? func() : new Result(Error); } /// /// Tries to chain a generic result to this result if it is a success, or does nothing if the result is a failure. If /// the function throws an exception, the exception will be returned wrapped in an . /// /// The function used to create the next generic result. /// The type of the new value. /// A result which is either the mapped result, the exception thrown by wrapped in /// an , or a new result containing the failure value of the original result. [Pure] public Result ThenTry(Func> func) { try { return Then(func); } catch (Exception exception) { return new Result(new ExceptionError(exception)); } } } public partial class Result { /// /// Maps the success of the result using an asynchronous mapping function, or does nothing if the result is /// a failure. /// /// The function used to map the success. /// The type of the new value. /// A which either completes asynchronously by invoking the mapping function and /// constructing a new result containing the mapped value, or completes synchronously by returning a new result /// containing the failure value of the original result. [Pure] public Task> MapAsync(Func> func) { if (!IsSuccess) { return Task.FromResult(new Result(Error)); } var task = func(); return CreateResult(task); static async Task> CreateResult(Task task) { var value = await task; return new Result(value); } } /// /// Maps the success of the result using an asynchronous mapping function, or does nothing if the result is a /// failure. If the mapping function throws an exception, the exception will be returned wrapped in an /// . /// /// The function used to map the success. /// The type of the new value. /// A which either completes asynchronously by invoking the mapping function and /// constructing a new result containing the mapped value, returning any exception thrown by /// wrapped in an or completes synchronously by returning a new result containing the /// failure value of the original result. [Pure] public Task> TryMapAsync(Func> func) { if (!IsSuccess) { return Task.FromResult(new Result(Error)); } try { var task = func(); return CreateResult(task); } catch (Exception exception) { return Task.FromResult(new Result(new ExceptionError(exception))); } static async Task> CreateResult(Task task) { try { var value = await task; return new Result(value); } catch (Exception exception) { return new Result(new ExceptionError(exception)); } } } /// /// Chains another result to this result using an asynchronous mapping function, or does nothing if the result is /// a failure. /// /// The function used to create the next result. /// A which either completes asynchronously by invoking the mapping function, or /// completes synchronously by returning a new result containing the failure value of the original result. [Pure] public Task ThenAsync(Func> func) { if (!IsSuccess) { return Task.FromResult(new Result(Error)); } var task = func(); return CreateResult(task); static async Task CreateResult(Task task) { var result = await task; return result; } } /// /// Tries to chain another result to this result using an asynchronous mapping function, or does nothing if the /// result is a failure. If the mapping function throws an exception, the exception will be returned wrapped in /// an . /// /// The function used to create the next result. /// A which either completes asynchronously by invoking the mapping function, /// returning any exception thrown by wrapped in an , or /// completes synchronously by returning a new result containing the failure value of the original result. [Pure] public Task ThenTryAsync(Func> func) { if (!IsSuccess) { return Task.FromResult(new Result(Error)); } try { var task = func(); return CreateResult(task); } catch (Exception exception) { return Task.FromResult(new Result(new ExceptionError(exception))); } static async Task CreateResult(Task task) { try { var value = await task; return value; } catch (Exception exception) { return new Result(new ExceptionError(exception)); } } } /// /// Chains a generic result to this result using an asynchronous mapping function, or does nothing if the result is /// a failure. /// /// The function used to create the next result. /// The type of the new value. /// A which either completes asynchronously by invoking the mapping function, or /// completes synchronously by returning a new result containing the failure value of the original result. [Pure] public Task> ThenAsync(Func>> func) { if (!IsSuccess) { return Task.FromResult(new Result(Error)); } var task = func(); return CreateResult(task); static async Task> CreateResult(Task> task) { var result = await task; return result; } } /// /// Tries to chain a generic result to this result using an asynchronous mapping function, or does nothing if the /// result is a failure. If the mapping function throws an exception, the exception will be returned wrapped in /// an . /// /// The function used to create the next result. /// The type of the new value. /// A which either completes asynchronously by invoking the mapping function, /// returning any exception thrown by wrapped in an , or /// completes synchronously by returning a new result containing the failure value of the original result. [Pure] public Task> ThenTryAsync(Func>> func) { if (!IsSuccess) { return Task.FromResult(new Result(Error)); } try { var task = func(); return CreateResult(task); } catch (Exception exception) { return Task.FromResult(new Result(new ExceptionError(exception))); } static async Task> CreateResult(Task> task) { try { var value = await task; return value; } catch (Exception exception) { return new Result(new ExceptionError(exception)); } } } } public partial class Result { /// /// Maps the success of the result using an asynchronous mapping function, or does nothing if the result is /// a failure. /// /// The function used to map the success. /// The type of the new value. /// A which either completes asynchronously by invoking the mapping function and /// constructing a new result containing the mapped value, or completes synchronously by returning a new result /// containing the failure value of the original result. [Pure] public ValueTask> MapAsync(Func> func) { if (!IsSuccess) { return ValueTask.FromResult(new Result(Error)); } var task = func(); return CreateResult(task); static async ValueTask> CreateResult(ValueTask task) { var value = await task; return new Result(value); } } /// /// Maps the success of the result using an asynchronous mapping function, or does nothing if the result is a /// failure. If the mapping function throws an exception, the exception will be returned wrapped in an /// . /// /// The function used to map the success. /// The type of the new value. /// A which either completes asynchronously by invoking the mapping function and /// constructing a new result containing the mapped value, returning any exception thrown by /// wrapped in an or completes synchronously by returning a new result containing the /// failure value of the original result. [Pure] public ValueTask> TryMapAsync(Func> func) { if (!IsSuccess) { return ValueTask.FromResult(new Result(Error)); } try { var task = func(); return CreateResult(task); } catch (Exception exception) { return ValueTask.FromResult(new Result(new ExceptionError(exception))); } static async ValueTask> CreateResult(ValueTask task) { try { var value = await task; return new Result(value); } catch (Exception exception) { return new Result(new ExceptionError(exception)); } } } /// /// Chains another result to this result using an asynchronous mapping function, or does nothing if the result is /// a failure. /// /// The function used to create the next result. /// A which either completes asynchronously by invoking the mapping function, or /// completes synchronously by returning a new result containing the failure value of the original result. [Pure] public ValueTask ThenAsync(Func> func) { if (!IsSuccess) { return ValueTask.FromResult(new Result(Error)); } var task = func(); return CreateResult(task); static async ValueTask CreateResult(ValueTask task) { var result = await task; return result; } } /// /// Tries to chain another result to this result using an asynchronous mapping function, or does nothing if the /// result is a failure. If the mapping function throws an exception, the exception will be returned wrapped in /// an . /// /// The function used to create the next result. /// A which either completes asynchronously by invoking the mapping function, /// returning any exception thrown by wrapped in an , or /// completes synchronously by returning a new result containing the failure value of the original result. [Pure] public ValueTask ThenTryAsync(Func> func) { if (!IsSuccess) { return ValueTask.FromResult(new Result(Error)); } try { var task = func(); return CreateResult(task); } catch (Exception exception) { return ValueTask.FromResult(new Result(new ExceptionError(exception))); } static async ValueTask CreateResult(ValueTask task) { try { var value = await task; return value; } catch (Exception exception) { return new Result(new ExceptionError(exception)); } } } /// /// Chains a generic result to this result using an asynchronous mapping function, or does nothing if the result is /// a failure. /// /// The function used to create the next result. /// The type of the new value. /// A which either completes asynchronously by invoking the mapping function, or /// completes synchronously by returning a new result containing the failure value of the original result. [Pure] public ValueTask> ThenAsync(Func>> func) { if (!IsSuccess) { return ValueTask.FromResult(new Result(Error)); } var task = func(); return CreateResult(task); static async ValueTask> CreateResult(ValueTask> task) { var result = await task; return result; } } /// /// Tries to chain a generic result to this result using an asynchronous mapping function, or does nothing if the /// result is a failure. If the mapping function throws an exception, the exception will be returned wrapped in /// an . /// /// The function used to create the next result. /// The type of the new value. /// A which either completes asynchronously by invoking the mapping function, /// returning any exception thrown by wrapped in an , or /// completes synchronously by returning a new result containing the failure value of the original result. [Pure] public ValueTask> ThenTryAsync(Func>> func) { if (!IsSuccess) { return ValueTask.FromResult(new Result(Error)); } try { var task = func(); return CreateResult(task); } catch (Exception exception) { return ValueTask.FromResult(new Result(new ExceptionError(exception))); } static async ValueTask> CreateResult(ValueTask> task) { try { var value = await task; return value; } catch (Exception exception) { return new Result(new ExceptionError(exception)); } } } }