Skip to content

Commit

Permalink
feat: added UnwrapOr that takes in an async lambda (#50)
Browse files Browse the repository at this point in the history
* feat: added UnwrapOr that takes in an async lambda

* feat: Add tests for async unwrap or

* fixing merge stuff

* missing return docs

* add task<maybe<T>> unwraporasync

* impl and tests for Task<Maybe> with sync func
  • Loading branch information
Chris Nantau authored Aug 5, 2021
1 parent 834887b commit 36a645a
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 5 deletions.
60 changes: 56 additions & 4 deletions wimm.Secundatives.UnitTests/Extensions/UnwrapOr_Test.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,15 @@ public class UnwrapOr_Test
{
private const string _valid = "doot";
private const string _default = "tood";
private readonly Func<string> _defaultFunc = () => _default;
private readonly Func<string> _defaultFunc = () => { _set = true; return _default; };
private readonly Func<Task<string>> _defaultAsyncFunc = async () => { _set = true; ; return await Task.FromResult(_default); };
private static bool _set = false;

public UnwrapOr_Test()
{
_set = false;
}

[Fact]
public void UnwrapOr_Value_ReturnsValue()
{
Expand Down Expand Up @@ -43,26 +49,72 @@ public void UnwrapOr_NoValue_ReturnsDefaultParam()
}

[Fact]
public async Task UnwrapOrAsync_NoValue_ExecutesFunction()
public async Task UnwrapOrAsyncFunc_NoValue_ExecutesFunction()
{
var underTest = new Maybe<string>();
Assert.Equal(_default, await underTest.UnwrapOr(_defaultAsyncFunc));
Assert.True(_set);
}

[Fact]
public async Task UnwrapOrAsync_Value_ReturnsValue()
public async Task UnwrapOrAsyncFunc_Value_ReturnsValue()
{
var underTest = new Maybe<string>(_valid);
Assert.Equal(_valid, await underTest.UnwrapOr(_defaultAsyncFunc));
}

[Fact]
public async Task UnwrapOrAsync_Value_DoesNotExecuteFunction()
public async Task UnwrapOrAsyncFunc_Value_DoesNotExecuteFunction()
{
var underTest = new Maybe<string>(_valid);
_ = await underTest.UnwrapOr(_defaultAsyncFunc);
Assert.False(_set);
}

[Fact]
public async Task UnwrapOrTaskMaybeAsyncFunc_Value_ReturnsValue()
{
var underTest = Task.FromResult(new Maybe<string>(_valid));
Assert.Equal(_valid, await underTest.UnwrapOr(_defaultAsyncFunc));
}

[Fact]
public async Task UnwrapOrTaskMaybeAsyncFunc_Value_DoesNotExecuteFunction()
{
var underTest = Task.FromResult(new Maybe<string>(_valid));
_ = await underTest.UnwrapOr(_defaultAsyncFunc);
Assert.False(_set);
}

[Fact]
public async Task UnwrapOrTaskMaybeAsyncFunc_NoValue_ExecutesFunction()
{
var underTest = Task.FromResult(new Maybe<string>());
Assert.Equal(_default, await underTest.UnwrapOr(_defaultAsyncFunc));
Assert.True(_set);
}

[Fact]
public async Task UnwrapOrTaskMaybe_Value_ReturnsValue()
{
var underTest = Task.FromResult(new Maybe<string>(_valid));
Assert.Equal(_valid, await underTest.UnwrapOr(_defaultFunc));
}

[Fact]
public async Task UnwrapOrTaskMaybe_Value_DoesNotExecuteFunction()
{
var underTest = Task.FromResult(new Maybe<string>(_valid));
_ = await underTest.UnwrapOr(_defaultFunc);
Assert.False(_set);
}

[Fact]
public async Task UnwrapOrTaskMaybe_NoValue_ExecutesFunction()
{
var underTest = Task.FromResult(new Maybe<string>());
Assert.Equal(_default, await underTest.UnwrapOr(_defaultFunc));
Assert.True(_set);
}
}
}
31 changes: 30 additions & 1 deletion wimm.Secundatives/Extensions/MaybeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public static async Task<T> Expect<T>(this Task<Maybe<T>> maybeTask)


/// <summary>
/// Unwraps the <see cref="Maybe{T}"/> if possible and returns a the results of a provided function otherwise
/// Unwraps the <see cref="Maybe{T}"/> if possible and returns the results of a provided function otherwise
/// </summary>
/// <typeparam name="T"> The type of value contained with the <paramref name="maybe"/> </typeparam>
/// <param name="maybe"> The <see cref="Maybe{T}"/> to be unwrapped </param>
Expand All @@ -103,6 +103,35 @@ public static async Task<T> Expect<T>(this Task<Maybe<T>> maybeTask)
/// the result of awaiting the execution of <paramref name="func"/> </returns>
public static async Task<T> UnwrapOr<T>(this Maybe<T> maybe, Func<Task<T>> func) => maybe.Exists ? maybe.Value : await func();


/// <summary>
/// Unwraps the <see cref="Maybe{T}"/> that results from the <see cref="Task"/> if possible and returns the results of awaiting the provided async function otherwise
/// </summary>
/// <typeparam name="T"> The type of value contained with the <paramref name="maybe"/> </typeparam>
/// <param name="maybe">A task resulting in a <see cref="Maybe{T}"/> to be inspected</param>
/// <param name="func"> A function that asynchronosly returns a <typeparamref name="T"/> that will be called if
/// unwrapping of <paramref name="maybe"/> is not possible </param>
/// <returns> The <typeparamref name="T"/> held within <paramref name="maybe"/> if it exists. Otherwise
/// the result of awaiting the execution of <paramref name="func"/> </returns>
public static async Task<T> UnwrapOr<T>(this Task<Maybe<T>> maybe, Func<Task<T>> func)
{
return await (await maybe).UnwrapOr(func);
}

/// <summary>
/// Unwraps the <see cref="Maybe{T}"/> that results from the <see cref="Task"/> if possible and returns the results of the provided function otherwise
/// </summary>
/// <typeparam name="T"> The type of value contained with the <paramref name="maybe"/> </typeparam>
/// <param name="maybe">A task resulting in a <see cref="Maybe{T}"/> to be inspected</param>
/// <param name="func"> A function that returns a <typeparamref name="T"/> that will be called if
/// unwrapping of <paramref name="maybe"/> is not possible </param>
/// <returns> The <typeparamref name="T"/> held within <paramref name="maybe"/> if it exists. Otherwise
/// the result of calling <paramref name="func"/> </returns>
public static async Task<T> UnwrapOr<T>(this Task<Maybe<T>> maybe, Func<T> func)
{
return (await maybe).UnwrapOr(func);
}

/// <summary>
/// An explicit conversion of class types to <see cref="Maybe{T}"/> for ease of use and compatibility
/// </summary>
Expand Down

0 comments on commit 36a645a

Please sign in to comment.