feat: add inital in memory dispatcher
All checks were successful
default / dotnet-default-workflow (push) Successful in 1m27s

Add a simple in memory dispatcher for scalar requests and stream request.
This commit is contained in:
Louis Seubert 2026-05-08 20:26:26 +02:00
commit 28c07c5c3f
Signed by: louis9902
GPG key ID: 4B9DB28F826553BD
145 changed files with 6380 additions and 0 deletions

View file

@ -0,0 +1,366 @@
// Copyright (c) The Geekeey Authors
// SPDX-License-Identifier: EUPL-1.2
using System.Diagnostics.Contracts;
namespace Geekeey.Request.Result;
public readonly partial struct Result<T>
{
/// <summary>
/// Maps the success value of the result using a mapping function, or does nothing if the result is a failure.
/// </summary>
/// <param name="func">The function used to map the success value.</param>
/// <typeparam name="TNew">The type of the new value.</typeparam>
/// <returns>A new result containing either the mapped success value or the failure value of the original
/// result.</returns>
[Pure]
public Result<TNew> Map<TNew>(Func<T, TNew> func)
{
return IsSuccess ? new Result<TNew>(func(Value!)) : new Result<TNew>(Error!);
}
/// <summary>
/// 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
/// <see cref="ExceptionError"/>.
/// </summary>
/// <param name="func">The function used to map the success value.</param>
/// <typeparam name="TNew">The type of the new value.</typeparam>
/// <returns>A new result containing either the mapped value, the exception thrown by <paramref name="func"/>
/// wrapped in an <see cref="ExceptionError"/>, or the failure value of the original result.</returns>
[Pure]
public Result<TNew> TryMap<TNew>(Func<T, TNew> func)
{
try
{
return Map(func);
}
catch (Exception exception)
{
return new Result<TNew>(new ExceptionError(exception));
}
}
/// <summary>
/// Maps the success value of the result to a new result using a mapping function, or does nothing if the result is
/// a failure.
/// </summary>
/// <param name="func">The function used to map the success value to a new result.</param>
/// <typeparam name="TNew">The type of the new value.</typeparam>
/// <returns>A result which is either the mapped result or a new result containing the failure value of the original
/// result.</returns>
[Pure]
public Result<TNew> Then<TNew>(Func<T, Result<TNew>> func)
{
return IsSuccess ? func(Value!) : new Result<TNew>(Error!);
}
/// <summary>
/// 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
/// <see cref="ExceptionError"/>.
/// </summary>
/// <param name="func">The function used to map the success value to a new result.</param>
/// <typeparam name="TNew">The type of the new value.</typeparam>
/// <returns>A result which is either the mapped result, the exception thrown by <paramref name="func"/> wrapped in
/// an <see cref="ExceptionError"/>, or a new result containing the failure value of the original result.</returns>
[Pure]
public Result<TNew> ThenTry<TNew>(Func<T, Result<TNew>> func)
{
try
{
return Then(func);
}
catch (Exception exception)
{
return new Result<TNew>(new ExceptionError(exception));
}
}
}
public readonly partial struct Result<T>
{
/// <summary>
/// Maps the success value of the result using an asynchronous mapping function, or does nothing if the result is
/// a failure.
/// </summary>
/// <param name="func">The function used to map the success value.</param>
/// <typeparam name="TNew">The type of the new value.</typeparam>
/// <returns>A <see cref="Task{T}"/> 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.</returns>
[Pure]
public Task<Result<TNew>> MapAsync<TNew>(Func<T, Task<TNew>> func)
{
if (!IsSuccess)
{
return Task.FromResult(new Result<TNew>(Error!));
}
var task = func(Value!);
return CreateResult(task);
static async Task<Result<TNew>> CreateResult(Task<TNew> task)
{
var value = await task;
return new Result<TNew>(value);
}
}
/// <summary>
/// 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
/// <see cref="ExceptionError"/>.
/// </summary>
/// <param name="func">The function used to map the success value.</param>
/// <typeparam name="TNew">The type of the new value.</typeparam>
/// <returns>A <see cref="Task{T}"/> 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 <paramref name="func"/> wrapped in an <see cref="ExceptionError"/> or completes synchronously by
/// returning a new result containing the failure value of the original result.</returns>
[Pure]
public Task<Result<TNew>> TryMapAsync<TNew>(Func<T, Task<TNew>> func)
{
if (!IsSuccess)
{
return Task.FromResult(new Result<TNew>(Error!));
}
try
{
var task = func(Value!);
return CreateResult(task);
}
catch (Exception exception)
{
return Task.FromResult(new Result<TNew>(new ExceptionError(exception)));
}
static async Task<Result<TNew>> CreateResult(Task<TNew> task)
{
try
{
var value = await task;
return new Result<TNew>(value);
}
catch (Exception exception)
{
return new Result<TNew>(new ExceptionError(exception));
}
}
}
/// <summary>
/// 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.
/// </summary>
/// <param name="func">The function used to map the success value to a new result.</param>
/// <typeparam name="TNew">The type of the new value.</typeparam>
/// <returns>A <see cref="Task{T}"/> 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.</returns>
[Pure]
public Task<Result<TNew>> ThenAsync<TNew>(Func<T, Task<Result<TNew>>> func)
{
if (!IsSuccess)
{
return Task.FromResult(new Result<TNew>(Error!));
}
var task = func(Value!);
return CreateResult(task);
static async Task<Result<TNew>> CreateResult(Task<Result<TNew>> task)
{
var result = await task;
return result;
}
}
/// <summary>
/// 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 <see cref="ExceptionError"/>.
/// </summary>
/// <param name="func">The function used to map the success value to a new result.</param>
/// <typeparam name="TNew">The type of the new value.</typeparam>
/// <returns>A <see cref="Task{T}"/> which either completes asynchronously by invoking the mapping function on
/// the success value of the result, returning any exception thrown by <paramref name="func"/> wrapped in an
/// <see cref="ExceptionError"/>, or completes synchronously by returning a new result containing the failure value
/// of the original result.</returns>
[Pure]
public Task<Result<TNew>> ThenTryAsync<TNew>(Func<T, Task<Result<TNew>>> func)
{
if (!IsSuccess)
{
return Task.FromResult(new Result<TNew>(Error!));
}
try
{
var task = func(Value!);
return CreateResult(task);
}
catch (Exception exception)
{
return Task.FromResult(new Result<TNew>(new ExceptionError(exception)));
}
static async Task<Result<TNew>> CreateResult(Task<Result<TNew>> task)
{
try
{
var value = await task;
return value;
}
catch (Exception exception)
{
return new Result<TNew>(new ExceptionError(exception));
}
}
}
}
public readonly partial struct Result<T>
{
/// <summary>
/// Maps the success value of the result using an asynchronous mapping function, or does nothing if the result is
/// a failure.
/// </summary>
/// <param name="func">The function used to map the success value.</param>
/// <typeparam name="TNew">The type of the new value.</typeparam>
/// <returns>A <see cref="ValueTask{T}"/> 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.</returns>
[Pure]
public ValueTask<Result<TNew>> MapAsync<TNew>(Func<T, ValueTask<TNew>> func)
{
if (!IsSuccess)
{
return ValueTask.FromResult(new Result<TNew>(Error!));
}
var task = func(Value!);
return CreateResult(task);
static async ValueTask<Result<TNew>> CreateResult(ValueTask<TNew> task)
{
var value = await task;
return new Result<TNew>(value);
}
}
/// <summary>
/// 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
/// <see cref="ExceptionError"/>.
/// </summary>
/// <param name="func">The function used to map the success value.</param>
/// <typeparam name="TNew">The type of the new value.</typeparam>
/// <returns>A <see cref="ValueTask{T}"/> 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 <paramref name="func"/> wrapped in an <see cref="ExceptionError"/> or completes synchronously by
/// returning a new result containing the failure value of the original result.</returns>
[Pure]
public ValueTask<Result<TNew>> TryMapAsync<TNew>(Func<T, ValueTask<TNew>> func)
{
if (!IsSuccess)
{
return ValueTask.FromResult(new Result<TNew>(Error!));
}
try
{
var task = func(Value!);
return CreateResult(task);
}
catch (Exception exception)
{
return ValueTask.FromResult(new Result<TNew>(new ExceptionError(exception)));
}
static async ValueTask<Result<TNew>> CreateResult(ValueTask<TNew> task)
{
try
{
var value = await task;
return new Result<TNew>(value);
}
catch (Exception exception)
{
return new Result<TNew>(new ExceptionError(exception));
}
}
}
/// <summary>
/// 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.
/// </summary>
/// <param name="func">The function used to map the success value to a new result.</param>
/// <typeparam name="TNew">The type of the new value.</typeparam>
/// <returns>A <see cref="ValueTask{T}"/> 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.</returns>
[Pure]
public ValueTask<Result<TNew>> ThenAsync<TNew>(Func<T, ValueTask<Result<TNew>>> func)
{
if (!IsSuccess)
{
return ValueTask.FromResult(new Result<TNew>(Error!));
}
var task = func(Value!);
return CreateResult(task);
static async ValueTask<Result<TNew>> CreateResult(ValueTask<Result<TNew>> task)
{
var result = await task;
return result;
}
}
/// <summary>
/// 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 <see cref="ExceptionError"/>.
/// </summary>
/// <param name="func">The function used to map the success value to a new result.</param>
/// <typeparam name="TNew">The type of the new value.</typeparam>
/// <returns>A <see cref="ValueTask{T}"/> which either completes asynchronously by invoking the mapping function on
/// the success value of the result, returning any exception thrown by <paramref name="func"/> wrapped in an
/// <see cref="ExceptionError"/>, or completes synchronously by returning a new result containing the failure value
/// of the original result.</returns>
[Pure]
public ValueTask<Result<TNew>> ThenTryAsync<TNew>(Func<T, ValueTask<Result<TNew>>> func)
{
if (!IsSuccess)
{
return ValueTask.FromResult(new Result<TNew>(Error!));
}
try
{
var task = func(Value!);
return CreateResult(task);
}
catch (Exception exception)
{
return ValueTask.FromResult(new Result<TNew>(new ExceptionError(exception)));
}
static async ValueTask<Result<TNew>> CreateResult(ValueTask<Result<TNew>> task)
{
try
{
var value = await task;
return value;
}
catch (Exception exception)
{
return new Result<TNew>(new ExceptionError(exception));
}
}
}
}