Skip to content

Commit

Permalink
Merge pull request #2 from thomaslevesque/getvalueor
Browse files Browse the repository at this point in the history
Replace GetValueOrDefault with specific extension methods
  • Loading branch information
thomaslevesque authored Sep 13, 2019
2 parents 0147ab0 + 1653fb7 commit 05db7a3
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 37 deletions.
15 changes: 6 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,15 @@ Option<int> option = ...
// Explicit check
if (option.IsSome)
{
return option.Value;
int value = option.Value;
...
}
else
{
return -1;
}

// Using GetValueOrDefault
return option.GetValueOrDefault(-1);

// Using TryGetValue
return option.TryGetValue(out var value) ? value : -1;
if (option.TryGetValue(out var value))
{
...
}
```

### Usage with Linq
Expand Down
7 changes: 7 additions & 0 deletions src/Hamlet/NullableAttributes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace System.Diagnostics.CodeAnalysis
{
/// <summary>Specifies that an output may be null even if the corresponding type disallows it.</summary>
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)]
internal sealed class MaybeNullAttribute : Attribute
{ }
}
44 changes: 44 additions & 0 deletions src/Hamlet/Option.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;

namespace Hamlet
{
Expand Down Expand Up @@ -142,6 +143,49 @@ public static U Match<T, U>(this Option<T> option, Func<T, U> some, Func<U> none
: default(T?);
}

/// <summary>
/// Returns the value of an <see cref="Option{T}"/> if the option is <c>Some</c>, or <c>null</c> if it's <c>None</c>.
/// </summary>
/// <typeparam name="T">The type of the option's value.</typeparam>
/// <param name="option">The option to get the value from.</param>
/// <returns>The option's value if it's <c>Some</c>, or <c>null</c> if it's <c>None</c>.</returns>
[return: MaybeNull]
public static T ValueOrNull<T>(this Option<T> option)
where T : class?
{
return option.IsSome
? option.Value
: null;
}

/// <summary>
/// Returns the value of an <see cref="Option{T}"/> if the option is <c>Some</c>, or <c>default(T)</c> if it's <c>None</c>.
/// </summary>
/// <typeparam name="T">The type of the option's value.</typeparam>
/// <param name="option">The option to get the value from.</param>
/// <returns>The option's value if it's <c>Some</c>, or <c>default(T)</c> if it's <c>None</c>.</returns>
public static T ValueOrDefault<T>(this Option<T> option)
where T : struct
{
return option.IsSome
? option.Value
: default;
}

/// <summary>
/// Returns the value of an <see cref="Option{T}"/> if the option is <c>Some</c>, or <c>defaultValue</c> if it's <c>None</c>.
/// </summary>
/// <typeparam name="T">The type of the option's value.</typeparam>
/// <param name="option">The option to get the value from.</param>
/// <param name="defaultValue">The value to return if the option is <c>None</c>.</param>
/// <returns>The option's value if it's <c>Some</c>, or <c>defaultValue</c> if it's <c>None</c>.</returns>
public static T ValueOr<T>(this Option<T> option, T defaultValue)
{
return option.IsSome
? option.Value
: defaultValue;
}

/// <summary>
/// Converts a <see cref="Nullable{T}"/> to an <see cref="Option{T}"/>, based on whether the nullable has a value.
/// </summary>
Expand Down
7 changes: 0 additions & 7 deletions src/Hamlet/OptionOfT.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,6 @@ public Option(T value)
/// </summary>
public bool IsNone => !IsSome;

/// <summary>
/// Attempts to get the option's value, if any, or a default value if the option has no value.
/// </summary>
/// <param name="defaultValue">The default value to return when the option has no value.</param>
/// <returns>The option's value, if any, <c>defaultValue</c> otherwise.</returns>
public T GetValueOrDefault(T defaultValue = default) => IsSome ? _value : defaultValue;

/// <summary>
/// Attempts to get the option's value, if any.
/// </summary>
Expand Down
21 changes: 0 additions & 21 deletions tests/Hamlet.Tests/OptionOfTTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,27 +50,6 @@ public void Value_throws_for_none()
exception.Should().BeOfType<InvalidOperationException>();
}

[Fact]
public void GetValueOrDefault_returns_value_for_some()
{
var option = Option.Some(42);
option.GetValueOrDefault().Should().Be(42);
}

[Fact]
public void GetValueOrDefault_returns_default_for_none()
{
var option = Option.None<int>();
option.GetValueOrDefault().Should().Be(0);
}

[Fact]
public void GetValueOrDefault_returns_specified_default_for_none()
{
var option = Option.None<int>();
option.GetValueOrDefault(3).Should().Be(3);
}

[Fact]
public void TryGetValue_returns_true_and_sets_value_for_some()
{
Expand Down
42 changes: 42 additions & 0 deletions tests/Hamlet.Tests/OptionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,48 @@ public void ToNullable_returns_value_for_some()
option.ToNullable().Should().Be(42);
}

[Fact]
public void ValueOrDefault_returns_value_for_some()
{
var option = Option.Some(42);
option.ValueOrDefault().Should().Be(42);
}

[Fact]
public void ValueOrDefault_returns_default_for_none()
{
var option = Option.None<int>();
option.ValueOrDefault().Should().Be(0);
}

[Fact]
public void ValueOrNull_returns_value_for_some()
{
var option = Option.Some("hello");
option.ValueOrNull().Should().Be("hello");
}

[Fact]
public void ValueOrNull_returns_null_for_none()
{
var option = Option.None<string>();
option.ValueOrNull().Should().BeNull();
}

[Fact]
public void ValueOr_returns_value_for_some()
{
var option = Option.Some(42);
option.ValueOr(3).Should().Be(42);
}

[Fact]
public void ValueOr_returns_default_for_none()
{
var option = Option.None<int>();
option.ValueOr(3).Should().Be(3);
}

[Fact]
public void SomeIfNotNull_nullable_returns_none_for_null()
{
Expand Down

0 comments on commit 05db7a3

Please sign in to comment.