// Copyright (c) The Geekeey Authors // SPDX-License-Identifier: EUPL-1.2 using System.Diagnostics.Contracts; namespace Geekeey.Request.Result; public readonly partial struct 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 readonly partial struct 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 readonly partial struct 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)); } } } }