Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 70 additions & 65 deletions src/All.Mvc/WrapModelBinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,97 +82,102 @@ string model

try
{
// Attempt to parse the value
var valueParsed = default(TValue) switch
// Attempt to parse value and wrap result
return Parse(value) switch
{
bool =>
M.ParseBool(value).Match(FNone, FSome),
TValue x =>
(result, ModelBindingResult.Success(Wrap(x))),

byte =>
M.ParseByte(value).Match(FNone, FSome),
_ when new MonadModelBinderProvider().GetBinder(typeof(TValue)) is IWrapModelBinder<TValue> x =>
x.GetValue(provider, model),

char =>
M.ParseChar(value).Match(FNone, FSome),
_ when JsonSerializer.Deserialize<TValue>($"\"{value}\"", WrapModelBinderHelpers.Options) is TValue x =>
(result, ModelBindingResult.Success(Wrap(x))),

DateOnly =>
M.ParseDateOnly(value).Match(FNone, FSome),
_ =>
Nothing()
};
}
catch
{
return Nothing();
}
}

DateTime =>
M.ParseDateTime(value).Match(FNone, FSome),
/// <summary>
/// Attempt to parse <paramref name="value"/>, returning null on failure.
/// </summary>
/// <param name="value">String value.</param>
/// <returns>Parsed value or null.</returns>
internal object? Parse(string? value) =>
default(TValue) switch
{
bool =>
M.ParseBool(value).Match(FNone, FSome),

DateTimeOffset =>
M.ParseDateTimeOffset(value).Match(FNone, FSome),
byte =>
M.ParseByte(value).Match(FNone, FSome),

decimal =>
M.ParseDecimal(value).Match(FNone, FSome),
char =>
M.ParseChar(value).Match(FNone, FSome),

double =>
M.ParseDouble(value).Match(FNone, FSome),
DateOnly =>
M.ParseDateOnly(value).Match(FNone, FSome),

Guid =>
M.ParseGuid(value).Match(FNone, FSome),
DateTime =>
M.ParseDateTime(value).Match(FNone, FSome),

short =>
M.ParseInt16(value).Match(FNone, FSome),
DateTimeOffset =>
M.ParseDateTimeOffset(value).Match(FNone, FSome),

int =>
M.ParseInt32(value).Match(FNone, FSome),
decimal =>
M.ParseDecimal(value).Match(FNone, FSome),

long =>
M.ParseInt64(value).Match(FNone, FSome),
double =>
M.ParseDouble(value).Match(FNone, FSome),

Int128 =>
M.ParseInt128(value).Match(FNone, FSome),
Guid =>
M.ParseGuid(value).Match(FNone, FSome),

nint =>
M.ParseIntPtr(value).Match(FNone, FSome),
short =>
M.ParseInt16(value).Match(FNone, FSome),

float =>
M.ParseSingle(value).Match(FNone, FSome),
int =>
M.ParseInt32(value).Match(FNone, FSome),

TimeOnly =>
M.ParseTimeOnly(value).Match(FNone, FSome),
long =>
M.ParseInt64(value).Match(FNone, FSome),

ushort =>
M.ParseUInt16(value).Match(FNone, FSome),
Int128 =>
M.ParseInt128(value).Match(FNone, FSome),

uint =>
M.ParseUInt32(value).Match(FNone, FSome),
nint =>
M.ParseIntPtr(value).Match(FNone, FSome),

ulong =>
M.ParseUInt64(value).Match(FNone, FSome),
float =>
M.ParseSingle(value).Match(FNone, FSome),

UInt128 =>
M.ParseUInt128(value).Match(FNone, FSome),
TimeOnly =>
M.ParseTimeOnly(value).Match(FNone, FSome),

nuint =>
M.ParseUIntPtr(value).Match(FNone, FSome),
ushort =>
M.ParseUInt16(value).Match(FNone, FSome),

_ =>
null
};
uint =>
M.ParseUInt32(value).Match(FNone, FSome),

// Wrap parsed value
return valueParsed switch
{
TValue x =>
(result, ModelBindingResult.Success(Wrap(x))),
ulong =>
M.ParseUInt64(value).Match(FNone, FSome),

_ when new MonadModelBinderProvider().GetBinder(typeof(TValue)) is IWrapModelBinder<TValue> x =>
x.GetValue(provider, model),
UInt128 =>
M.ParseUInt128(value).Match(FNone, FSome),

_ when JsonSerializer.Deserialize<TValue>($"\"{value}\"", WrapModelBinderHelpers.Options) is TValue x =>
(result, ModelBindingResult.Success(Wrap(x))),
nuint =>
M.ParseUIntPtr(value).Match(FNone, FSome),

_ =>
Nothing()
};
}
catch
{
return Nothing();
}
}
_ =>
null
};

/// <summary>
/// Return a 'None' or null value.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,16 @@ public static partial class EnumerableExtensions
/// <param name="this">IEnumerable object.</param>
/// <param name="index">Index of value to return.</param>
/// <returns>Value of the element at position <paramref name="index"/> of <paramref name="this"/>, or <see cref="None"/>.</returns>
public static Maybe<T> ElementAtOrNone<T>(this IEnumerable<T> @this, int index) =>
(@this.Count() > index) switch
public static Maybe<T> ElementAtOrNone<T>(this IEnumerable<T> @this, int index)
{
var a = @this.ToArray();
return (index < a.Length) switch
{
true =>
@this.ElementAt(index),
a[index],

false =>
M.None
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,16 @@ public static partial class EnumerableExtensions
/// <typeparam name="T">IEnumerable value type.</typeparam>
/// <param name="this">IEnumerable object</param>
/// <returns>Value of the first element of <paramref name="this"/>, or <see cref="None"/>.</returns>
public static Maybe<T> FirstOrNone<T>(this IEnumerable<T> @this) =>
@this.Any() switch
public static Maybe<T> FirstOrNone<T>(this IEnumerable<T> @this)
{
var a = @this.ToArray();
return (a.Length > 0) switch
{
true =>
@this.First(),
a[0],

_ =>
false =>
M.None
};
}
}
11 changes: 7 additions & 4 deletions src/All/Extensions/Enumerable/EnumerableExtensions.LastOrNone.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,16 @@ public static partial class EnumerableExtensions
/// <typeparam name="T">IEnumerable value type.</typeparam>
/// <param name="this">IEnumerable object</param>
/// <returns>Value of the last element of <paramref name="this"/>, or <see cref="None"/>.</returns>
public static Maybe<T> LastOrNone<T>(this IEnumerable<T> @this) =>
@this.Any() switch
public static Maybe<T> LastOrNone<T>(this IEnumerable<T> @this)
{
var a = @this.ToArray();
return (a.Length > 0) switch
{
true =>
@this.Last(),
a[^1],

_ =>
false =>
M.None
};
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Wrap: Functional Monads for .NET
// Copyright (c) bfren - licensed under https://mit.bfren.dev/2019

using System;
using System.Collections.Generic;
using System.Linq;

Expand All @@ -18,13 +17,16 @@ public static partial class EnumerableExtensions
/// Value of the single element of <paramref name="this"/>, or <see cref="None"/> if the list is empty
/// or contains more than one element.
/// </returns>
public static Maybe<T> SingleOrNone<T>(this IEnumerable<T> @this) =>
@this.Count() switch
public static Maybe<T> SingleOrNone<T>(this IEnumerable<T> @this)
{
var a = @this.ToArray();
return (a.Length == 1) switch
{
1 =>
@this.Single(),
true =>
a[0],

_ =>
false =>
M.None
};
}
}
Loading
Loading