mirror of
https://github.com/AlexMacocian/SystemExtensions.git
synced 2026-07-15 14:19:29 +00:00
Remove deprecated packages
This commit is contained in:
@@ -8,7 +8,7 @@
|
|||||||
<RootNamespace>System</RootNamespace>
|
<RootNamespace>System</RootNamespace>
|
||||||
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
||||||
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
|
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
|
||||||
<Version>1.8</Version>
|
<Version>1.9</Version>
|
||||||
<Authors>Alexandru Macocian</Authors>
|
<Authors>Alexandru Macocian</Authors>
|
||||||
<RepositoryUrl>https://github.com/AlexMacocian/SystemExtensions</RepositoryUrl>
|
<RepositoryUrl>https://github.com/AlexMacocian/SystemExtensions</RepositoryUrl>
|
||||||
<Description>Extensions for the System namespace</Description>
|
<Description>Extensions for the System namespace</Description>
|
||||||
|
|||||||
@@ -1,31 +1,7 @@
|
|||||||
using Newtonsoft.Json;
|
namespace System.Extensions;
|
||||||
|
|
||||||
namespace System.Extensions;
|
|
||||||
|
|
||||||
public static class ObjectExtensions
|
public static class ObjectExtensions
|
||||||
{
|
{
|
||||||
public static T? Deserialize<T>(this string serialized)
|
|
||||||
where T : class
|
|
||||||
{
|
|
||||||
if (serialized.IsNullOrWhiteSpace())
|
|
||||||
{
|
|
||||||
throw new ArgumentException("Provided serialized string cannot be null or whitespace", nameof(serialized));
|
|
||||||
}
|
|
||||||
|
|
||||||
return JsonConvert.DeserializeObject<T>(serialized);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string Serialize<T>(this T obj)
|
|
||||||
where T : class
|
|
||||||
{
|
|
||||||
if (obj is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(obj));
|
|
||||||
}
|
|
||||||
|
|
||||||
return JsonConvert.SerializeObject(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static T Cast<T>(this object obj)
|
public static T Cast<T>(this object obj)
|
||||||
{
|
{
|
||||||
return (T)obj;
|
return (T)obj;
|
||||||
@@ -36,11 +12,6 @@ public static class ObjectExtensions
|
|||||||
return obj as T;
|
return obj as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Optional<T> ToOptional<T>(this T obj)
|
|
||||||
{
|
|
||||||
return Optional.FromValue(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static T ThrowIfNull<T>([ValidatedNotNull] this T? obj, string name) where T : class
|
public static T ThrowIfNull<T>([ValidatedNotNull] this T? obj, string name) where T : class
|
||||||
{
|
{
|
||||||
if (obj is null)
|
if (obj is null)
|
||||||
|
|||||||
@@ -1,193 +0,0 @@
|
|||||||
namespace System.Extensions;
|
|
||||||
|
|
||||||
public static class Optional
|
|
||||||
{
|
|
||||||
public static Optional<T> None<T>()
|
|
||||||
{
|
|
||||||
return new Optional<T>.None();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Optional<T> FromValue<T>(T? value)
|
|
||||||
{
|
|
||||||
if (value == null)
|
|
||||||
{
|
|
||||||
return new Optional<T>.None();
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Optional<T>.Some(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class Optional<T> : IEquatable<Optional<T>>
|
|
||||||
{
|
|
||||||
public Optional(T value)
|
|
||||||
{
|
|
||||||
this.Value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private T Value { get; }
|
|
||||||
|
|
||||||
public T? ExtractValue()
|
|
||||||
{
|
|
||||||
if (this is None)
|
|
||||||
{
|
|
||||||
return default;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return this.Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public Optional<T> Do(Action<T>? onSome, Action? onNone)
|
|
||||||
{
|
|
||||||
if (onSome is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(onSome));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (onNone is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(onNone));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this is Some)
|
|
||||||
{
|
|
||||||
onSome.Invoke(this.Value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
onNone.Invoke();
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
public Optional<T> DoAny(Action<T>? onSome = default, Action? onNone = default)
|
|
||||||
{
|
|
||||||
if (this is Some)
|
|
||||||
{
|
|
||||||
onSome?.Invoke(this.Value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
onNone?.Invoke();
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
public Optional<V> Switch<V>(Func<T, V>? onSome, Func<V>? onNone)
|
|
||||||
{
|
|
||||||
if (onSome is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException($"{nameof(onSome)}");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (onNone is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException($"{nameof(onNone)}");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this is Some)
|
|
||||||
{
|
|
||||||
return Optional.FromValue(onSome.Invoke(this.Value));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return Optional.FromValue(onNone.Invoke());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public Optional<V> SwitchAny<V>(Func<T, V>? onSome = null, Func<V>? onNone = null)
|
|
||||||
{
|
|
||||||
if (this is Some)
|
|
||||||
{
|
|
||||||
return onSome != null ? Optional.FromValue(onSome.Invoke(this.Value)) : Optional.FromValue(default(V));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return onNone != null ? Optional.FromValue(onNone.Invoke()) : Optional.FromValue(default(V));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Equals(object? obj)
|
|
||||||
{
|
|
||||||
if (obj is Optional<T>)
|
|
||||||
{
|
|
||||||
return this.Equals(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
return base.Equals(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Equals(Optional<T>? other)
|
|
||||||
{
|
|
||||||
if (this is Some && other is Some)
|
|
||||||
{
|
|
||||||
return this.As<Some>() is Some some ? some.Equals(other.As<Some>()) : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static implicit operator Optional<T>(T? value)
|
|
||||||
{
|
|
||||||
return Optional.FromValue(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode()
|
|
||||||
{
|
|
||||||
return this.Value == null ? base.GetHashCode() : this.Value.GetHashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class Some : Optional<T>, IEquatable<Some>
|
|
||||||
{
|
|
||||||
public Some(T value) : base(value)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Equals(object? obj)
|
|
||||||
{
|
|
||||||
if (obj is Some)
|
|
||||||
{
|
|
||||||
return this.Equals(obj.As<Some>());
|
|
||||||
}
|
|
||||||
|
|
||||||
return base.Equals(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Equals(Some? other)
|
|
||||||
{
|
|
||||||
if (other is None)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (other is not null)
|
|
||||||
{
|
|
||||||
return this.Value is not null && this.Value.Equals(other.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator ==(Some? left, Some right)
|
|
||||||
{
|
|
||||||
return left?.Equals(right) == true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator !=(Some? left, Some right)
|
|
||||||
{
|
|
||||||
return left?.Equals(right) != true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode()
|
|
||||||
{
|
|
||||||
return this.Value is object ? this.Value.GetHashCode() : this.As<object>() is object obj ? obj.GetHashCode() : 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class None : Optional<T>
|
|
||||||
{
|
|
||||||
public None() : base(default!)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,216 +0,0 @@
|
|||||||
namespace System.Extensions;
|
|
||||||
|
|
||||||
public class Result<TSuccess, TFailure>
|
|
||||||
{
|
|
||||||
private readonly object? value;
|
|
||||||
|
|
||||||
public Result(TSuccess successValue)
|
|
||||||
{
|
|
||||||
this.value = successValue;
|
|
||||||
}
|
|
||||||
public Result(TFailure failureValue)
|
|
||||||
{
|
|
||||||
this.value = failureValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TryExtractSuccess(out TSuccess? successValue)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (this.value is TSuccess success)
|
|
||||||
{
|
|
||||||
successValue = success;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
successValue = default;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public bool TryExtractFailure(out TFailure? failureValue)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (this.value is TFailure failure)
|
|
||||||
{
|
|
||||||
failureValue = failure;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
failureValue = default;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public Result<TSuccess, TFailure> Do(Action onSuccess, Action onFailure)
|
|
||||||
{
|
|
||||||
if (onSuccess is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(onSuccess));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (onFailure is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(onFailure));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.value is TSuccess)
|
|
||||||
{
|
|
||||||
onSuccess.Invoke();
|
|
||||||
}
|
|
||||||
else if (this.value is TFailure)
|
|
||||||
{
|
|
||||||
onFailure.Invoke();
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
public Result<TSuccess, TFailure> DoAny(Action? onSuccess = null, Action? onFailure = null)
|
|
||||||
{
|
|
||||||
if (this.value is TSuccess)
|
|
||||||
{
|
|
||||||
onSuccess?.Invoke();
|
|
||||||
}
|
|
||||||
else if (this.value is TFailure)
|
|
||||||
{
|
|
||||||
onFailure?.Invoke();
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
public Result<TSuccess, TFailure> Do(Action<TSuccess> onSuccess, Action<TFailure> onFailure)
|
|
||||||
{
|
|
||||||
if (onSuccess is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(onSuccess));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (onFailure is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(onFailure));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.value is TSuccess success)
|
|
||||||
{
|
|
||||||
onSuccess.Invoke(success);
|
|
||||||
}
|
|
||||||
else if (this.value is TFailure failure)
|
|
||||||
{
|
|
||||||
onFailure.Invoke(failure);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
public Result<TSuccess, TFailure> DoAny(Action<TSuccess>? onSuccess = null, Action<TFailure>? onFailure = null)
|
|
||||||
{
|
|
||||||
if (this.value is TSuccess success)
|
|
||||||
{
|
|
||||||
onSuccess?.Invoke(success);
|
|
||||||
}
|
|
||||||
else if (this.value is TFailure failure)
|
|
||||||
{
|
|
||||||
onFailure?.Invoke(failure);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
public T Switch<T>(Func<TSuccess, T> onSuccess, Func<TFailure, T> onFailure)
|
|
||||||
{
|
|
||||||
if (onSuccess is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(onSuccess));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (onFailure is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(onFailure));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.value is TSuccess success)
|
|
||||||
{
|
|
||||||
return onSuccess.Invoke(success);
|
|
||||||
}
|
|
||||||
else if (this.value is TFailure failure)
|
|
||||||
{
|
|
||||||
return onFailure.Invoke(failure);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new InvalidOperationException($"{nameof(this.value)} must be of type {typeof(TSuccess)} or {typeof(TFailure)} in order to switch to {typeof(T)}");
|
|
||||||
}
|
|
||||||
public T? SwitchAny<T>(Func<TSuccess, T>? onSuccess = null, Func<TFailure, T>? onFailure = null)
|
|
||||||
{
|
|
||||||
if (this.value is TSuccess success)
|
|
||||||
{
|
|
||||||
return onSuccess is null ? default : onSuccess.Invoke(success);
|
|
||||||
}
|
|
||||||
else if (this.value is TFailure failure)
|
|
||||||
{
|
|
||||||
return onFailure is null ? default : onFailure.Invoke(failure);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new InvalidOperationException($"{nameof(this.value)} must be of type {typeof(TSuccess)} or {typeof(TFailure)} in order to switch to {typeof(T)}");
|
|
||||||
}
|
|
||||||
public Result<V, K> Switch<V, K>(Func<TSuccess, V> onSuccess, Func<TFailure, K> onFailure)
|
|
||||||
{
|
|
||||||
if (onSuccess is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(onSuccess));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (onFailure is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(onFailure));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.value is TSuccess success)
|
|
||||||
{
|
|
||||||
return Result<V, K>.Success(onSuccess.Invoke(success));
|
|
||||||
}
|
|
||||||
else if (this.value is TFailure failure)
|
|
||||||
{
|
|
||||||
return Result<V, K>.Failure(onFailure.Invoke(failure));
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new InvalidOperationException($"{nameof(this.value)} must be of type {typeof(TSuccess)} or {typeof(TFailure)} in order to switch to Result of type {typeof(V)} or {typeof(K)}");
|
|
||||||
}
|
|
||||||
public Result<V, K> SwitchAny<V, K>(Func<TSuccess, V> onSuccess, Func<TFailure, K> onFailure)
|
|
||||||
{
|
|
||||||
if (this.value is TSuccess success)
|
|
||||||
{
|
|
||||||
return Result<V, K>.Success(onSuccess is not null ? onSuccess.Invoke(success) : default!);
|
|
||||||
}
|
|
||||||
else if (this.value is TFailure failure)
|
|
||||||
{
|
|
||||||
return Result<V, K>.Failure(onFailure is not null ? onFailure.Invoke(failure) : default!);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new InvalidOperationException($"{nameof(this.value)} must be of type {typeof(TSuccess)} or {typeof(TFailure)} in order to switch to Result of type {typeof(V)} or {typeof(K)}");
|
|
||||||
}
|
|
||||||
public Optional<TSuccess> ToOptional()
|
|
||||||
{
|
|
||||||
if (this.value is TSuccess)
|
|
||||||
{
|
|
||||||
return Optional.FromValue(this.value.Cast<TSuccess>());
|
|
||||||
}
|
|
||||||
|
|
||||||
return Optional.None<TSuccess>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static implicit operator Result<TSuccess, TFailure>(TSuccess success)
|
|
||||||
{
|
|
||||||
return Success(success);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static implicit operator Result<TSuccess, TFailure>(TFailure failure)
|
|
||||||
{
|
|
||||||
return Failure(failure);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Result<TSuccess, TFailure> Success(TSuccess value)
|
|
||||||
{
|
|
||||||
return new Result<TSuccess, TFailure>(value);
|
|
||||||
}
|
|
||||||
public static Result<TSuccess, TFailure> Failure(TFailure value)
|
|
||||||
{
|
|
||||||
return new Result<TSuccess, TFailure>(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -5,27 +5,6 @@ namespace System.Extensions;
|
|||||||
|
|
||||||
public static class StreamExtensions
|
public static class StreamExtensions
|
||||||
{
|
{
|
||||||
public static void DoWhileReading(this Stream stream, Action<int, byte[]> action, int bufferLength = 256)
|
|
||||||
{
|
|
||||||
if (stream is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(stream));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (action is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(action));
|
|
||||||
}
|
|
||||||
|
|
||||||
var buffer = new byte[bufferLength];
|
|
||||||
var read = stream.Read(buffer, 0, bufferLength);
|
|
||||||
while(read > 0)
|
|
||||||
{
|
|
||||||
action(bufferLength, buffer);
|
|
||||||
read = stream.Read(buffer, 0, bufferLength);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] ReadBytes(this Stream stream, int count)
|
public static byte[] ReadBytes(this Stream stream, int count)
|
||||||
{
|
{
|
||||||
if (stream is null)
|
if (stream is null)
|
||||||
|
|||||||
@@ -1,185 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace System.Extensions;
|
|
||||||
|
|
||||||
public static class TaskExtensions
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Mark task as <see cref="TaskCreationOptions.LongRunning"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">Result type.</typeparam>
|
|
||||||
/// <param name="task">Task.</param>
|
|
||||||
/// <returns>The started <see cref="Task{TResult}"/></returns>
|
|
||||||
public static Task<T> LongRunning<T>(this Task<T> task)
|
|
||||||
{
|
|
||||||
return Task.Factory.StartNew(async () =>
|
|
||||||
{
|
|
||||||
return await task;
|
|
||||||
}, TaskCreationOptions.LongRunning).Unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Mark task as <see cref="TaskCreationOptions.LongRunning"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="task">Task.</param>
|
|
||||||
/// <returns>The started <see cref="Task"/></returns>
|
|
||||||
public static Task LongRunning(this Task task)
|
|
||||||
{
|
|
||||||
return Task.Factory.StartNew(async () =>
|
|
||||||
{
|
|
||||||
await task;
|
|
||||||
}, TaskCreationOptions.LongRunning).Unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Execute action periodically and asynchronously.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="onTick">Action to be executed.</param>
|
|
||||||
/// <param name="dueTime">Time to pass before starting to execute.</param>
|
|
||||||
/// <param name="interval">Interval between procs.</param>
|
|
||||||
/// <param name="token">Cancellation token used to cancel the cycle.</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static async Task RunPeriodicAsync(this Action onTick, TimeSpan dueTime, TimeSpan interval, CancellationToken token)
|
|
||||||
{
|
|
||||||
if (dueTime > TimeSpan.Zero)
|
|
||||||
{
|
|
||||||
await Task.Delay(dueTime, token).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!token.IsCancellationRequested)
|
|
||||||
{
|
|
||||||
onTick?.Invoke();
|
|
||||||
if (interval > TimeSpan.Zero)
|
|
||||||
{
|
|
||||||
await Task.Delay(interval, token).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Execute's an async Task<T> method which has a void return value synchronously
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="task">Task<T> method to execute</param>
|
|
||||||
public static void RunSync(this Func<Task> task)
|
|
||||||
{
|
|
||||||
var oldContext = SynchronizationContext.Current;
|
|
||||||
var synch = new ExclusiveSynchronizationContext();
|
|
||||||
SynchronizationContext.SetSynchronizationContext(synch);
|
|
||||||
synch.Post(async _ =>
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await task();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
synch.InnerException = e;
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
synch.EndMessageLoop();
|
|
||||||
}
|
|
||||||
}, default!);
|
|
||||||
synch.BeginMessageLoop();
|
|
||||||
|
|
||||||
SynchronizationContext.SetSynchronizationContext(oldContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Execute's an async Task<T> method which has a T return type synchronously
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">Return Type</typeparam>
|
|
||||||
/// <param name="task">Task<T> method to execute</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static T RunSync<T>(this Func<Task<T>> task)
|
|
||||||
{
|
|
||||||
var oldContext = SynchronizationContext.Current;
|
|
||||||
var synch = new ExclusiveSynchronizationContext();
|
|
||||||
SynchronizationContext.SetSynchronizationContext(synch);
|
|
||||||
var ret = default(T);
|
|
||||||
synch.Post(async _ =>
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ret = await task();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
synch.InnerException = e;
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
synch.EndMessageLoop();
|
|
||||||
}
|
|
||||||
}, default!);
|
|
||||||
synch.BeginMessageLoop();
|
|
||||||
SynchronizationContext.SetSynchronizationContext(oldContext);
|
|
||||||
return ret!;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ExclusiveSynchronizationContext : SynchronizationContext
|
|
||||||
{
|
|
||||||
private bool done;
|
|
||||||
public Exception? InnerException { get; set; }
|
|
||||||
readonly AutoResetEvent workItemsWaiting = new AutoResetEvent(false);
|
|
||||||
readonly Queue<Tuple<SendOrPostCallback, object>> items =
|
|
||||||
new Queue<Tuple<SendOrPostCallback, object>>();
|
|
||||||
|
|
||||||
public override void Send(SendOrPostCallback d, object state)
|
|
||||||
{
|
|
||||||
throw new NotSupportedException("We cannot send to our same thread");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Post(SendOrPostCallback d, object state)
|
|
||||||
{
|
|
||||||
lock (this.items)
|
|
||||||
{
|
|
||||||
this.items.Enqueue(Tuple.Create(d, state));
|
|
||||||
}
|
|
||||||
|
|
||||||
this.workItemsWaiting.Set();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void EndMessageLoop()
|
|
||||||
{
|
|
||||||
this.Post(_ => this.done = true, default!);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void BeginMessageLoop()
|
|
||||||
{
|
|
||||||
while (!this.done)
|
|
||||||
{
|
|
||||||
Tuple<SendOrPostCallback, object> task = default!;
|
|
||||||
lock (this.items)
|
|
||||||
{
|
|
||||||
if (this.items.Count > 0)
|
|
||||||
{
|
|
||||||
task = this.items.Dequeue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (task != null)
|
|
||||||
{
|
|
||||||
task.Item1(task.Item2);
|
|
||||||
if (this.InnerException != null) // the method threw an exeption
|
|
||||||
{
|
|
||||||
throw new AggregateException("AsyncHelpers.Run method threw an exception.", this.InnerException);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.workItemsWaiting.WaitOne();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override SynchronizationContext CreateCopy()
|
|
||||||
{
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
||||||
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
|
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
|
||||||
<RootNamespace>System</RootNamespace>
|
<RootNamespace>System</RootNamespace>
|
||||||
<Version>1.8</Version>
|
<Version>1.9</Version>
|
||||||
<Authors>Alexandru Macocian</Authors>
|
<Authors>Alexandru Macocian</Authors>
|
||||||
<RepositoryUrl>https://github.com/AlexMacocian/SystemExtensions</RepositoryUrl>
|
<RepositoryUrl>https://github.com/AlexMacocian/SystemExtensions</RepositoryUrl>
|
||||||
<Description>Extensions for the System namespace</Description>
|
<Description>Extensions for the System namespace</Description>
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.1" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.1" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="System.Text.Json" Version="10.0.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,110 +0,0 @@
|
|||||||
using FluentAssertions;
|
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
|
|
||||||
namespace System.Extensions.Tests;
|
|
||||||
|
|
||||||
[TestClass]
|
|
||||||
public class OptionalTests
|
|
||||||
{
|
|
||||||
[TestMethod]
|
|
||||||
public void SomeValueShouldEqualOptional()
|
|
||||||
{
|
|
||||||
var value = string.Empty;
|
|
||||||
var optional = value.ToOptional();
|
|
||||||
|
|
||||||
Assert.IsTrue(optional.Equals(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void OptionalFromNullShouldNotEqual()
|
|
||||||
{
|
|
||||||
object value = null;
|
|
||||||
var optional = value.ToOptional();
|
|
||||||
|
|
||||||
Assert.IsFalse(optional.Equals(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void OptionalFromValueShouldBeSome()
|
|
||||||
{
|
|
||||||
var optional = Optional.FromValue<object>(new object());
|
|
||||||
|
|
||||||
optional.DoAny(
|
|
||||||
onNone: () => throw new InvalidOperationException());
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void OptionalFromNullShouldBeNone()
|
|
||||||
{
|
|
||||||
var optional = Optional.FromValue<object>(null);
|
|
||||||
|
|
||||||
optional.DoAny(
|
|
||||||
onSome: _ => throw new InvalidOperationException());
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void DoShouldExecute()
|
|
||||||
{
|
|
||||||
var optional = Optional.FromValue(string.Empty);
|
|
||||||
var nullOptional = Optional.FromValue<string>(null);
|
|
||||||
|
|
||||||
optional.Do(
|
|
||||||
onSome: _ => { },
|
|
||||||
onNone: () => throw new InvalidOperationException());
|
|
||||||
|
|
||||||
nullOptional.Do(
|
|
||||||
onSome: _ => throw new InvalidOperationException(),
|
|
||||||
onNone: () => { });
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void DoAnyShouldExecute()
|
|
||||||
{
|
|
||||||
var optional = Optional.FromValue(string.Empty);
|
|
||||||
var nullOptional = Optional.FromValue<string>(null);
|
|
||||||
|
|
||||||
optional.DoAny(
|
|
||||||
onNone: () => throw new InvalidOperationException());
|
|
||||||
|
|
||||||
nullOptional.DoAny(
|
|
||||||
onSome: _ => throw new InvalidOperationException());
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void SwitchShouldExecute()
|
|
||||||
{
|
|
||||||
var optional = Optional.FromValue(string.Empty);
|
|
||||||
var nullOptional = Optional.FromValue<string>(null);
|
|
||||||
|
|
||||||
var newValue = optional.Switch(
|
|
||||||
onSome: _ => string.Empty,
|
|
||||||
onNone: () => throw new InvalidOperationException())
|
|
||||||
.ExtractValue();
|
|
||||||
|
|
||||||
var newNullValue = nullOptional.Switch<string>(
|
|
||||||
onSome: _ => throw new InvalidOperationException(),
|
|
||||||
onNone: () => null)
|
|
||||||
.ExtractValue();
|
|
||||||
|
|
||||||
newValue.Should().Be(string.Empty);
|
|
||||||
newNullValue.Should().Be(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void SwitchAnyShouldExecute()
|
|
||||||
{
|
|
||||||
var optional = Optional.FromValue(string.Empty);
|
|
||||||
var nullOptional = Optional.FromValue<string>(null);
|
|
||||||
|
|
||||||
var newValue = optional.SwitchAny(
|
|
||||||
onSome: _ => string.Empty)
|
|
||||||
.ExtractValue();
|
|
||||||
|
|
||||||
var newNullValue = nullOptional.SwitchAny<string>(
|
|
||||||
onNone: () => null)
|
|
||||||
.ExtractValue();
|
|
||||||
|
|
||||||
newValue.Should().Be(string.Empty);
|
|
||||||
newNullValue.Should().Be(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
using FluentAssertions;
|
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
|
|
||||||
namespace System.Extensions.Tests;
|
|
||||||
|
|
||||||
[TestClass]
|
|
||||||
public class ResultTests
|
|
||||||
{
|
|
||||||
[TestMethod]
|
|
||||||
public void SuccessResultShouldCreateFromSuccess()
|
|
||||||
{
|
|
||||||
var success = string.Empty;
|
|
||||||
var result = Result<string, object>.Success(success);
|
|
||||||
|
|
||||||
result.DoAny(
|
|
||||||
onFailure: () => throw new InvalidOperationException());
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void FailureResultShouldCreateFromFailure()
|
|
||||||
{
|
|
||||||
var failure = new object();
|
|
||||||
var result = Result<string, object>.Failure(failure);
|
|
||||||
|
|
||||||
result.DoAny(
|
|
||||||
onSuccess: () => throw new InvalidOperationException());
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void DoShouldExecute()
|
|
||||||
{
|
|
||||||
var success = string.Empty;
|
|
||||||
var successResult = Result<string, object>.Success(success);
|
|
||||||
|
|
||||||
var failure = new object();
|
|
||||||
var failedResult = Result<string, object>.Failure(failure);
|
|
||||||
|
|
||||||
successResult.Do(
|
|
||||||
onSuccess: _ => { },
|
|
||||||
onFailure: _ => throw new InvalidOperationException());
|
|
||||||
|
|
||||||
failedResult.Do(
|
|
||||||
onSuccess: _ => throw new InvalidOperationException(),
|
|
||||||
onFailure: _ => { });
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void DoAnyShouldExecute()
|
|
||||||
{
|
|
||||||
var success = string.Empty;
|
|
||||||
var successResult = Result<string, object>.Success(success);
|
|
||||||
|
|
||||||
var failure = new object();
|
|
||||||
var failedResult = Result<string, object>.Failure(failure);
|
|
||||||
|
|
||||||
successResult.DoAny(
|
|
||||||
onSuccess: _ => { });
|
|
||||||
|
|
||||||
failedResult.DoAny(
|
|
||||||
onFailure: _ => { });
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void SwitchShouldExecute()
|
|
||||||
{
|
|
||||||
var success = string.Empty;
|
|
||||||
var successResult = Result<string, object>.Success(success);
|
|
||||||
|
|
||||||
var failure = new object();
|
|
||||||
var failedResult = Result<string, object>.Failure(failure);
|
|
||||||
|
|
||||||
var successSwitch = successResult.Switch(
|
|
||||||
onSuccess: _ => string.Empty,
|
|
||||||
onFailure: _ => throw new InvalidOperationException());
|
|
||||||
|
|
||||||
var failedSwitch = failedResult.Switch(
|
|
||||||
onSuccess: _ => throw new InvalidOperationException(),
|
|
||||||
onFailure: _ => string.Empty);
|
|
||||||
|
|
||||||
success.Should().Be(failedSwitch);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void SwitchAnyShouldExecute()
|
|
||||||
{
|
|
||||||
var success = string.Empty;
|
|
||||||
var successResult = Result<string, object>.Success(success);
|
|
||||||
|
|
||||||
var failure = new object();
|
|
||||||
var failedResult = Result<string, object>.Failure(failure);
|
|
||||||
|
|
||||||
var successSwitch = successResult.SwitchAny(
|
|
||||||
onSuccess: _ => string.Empty);
|
|
||||||
|
|
||||||
var failedSwitch = failedResult.SwitchAny(
|
|
||||||
onFailure: _ => string.Empty);
|
|
||||||
|
|
||||||
success.Should().Be(failedSwitch);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void ToOptionalShouldConvert()
|
|
||||||
{
|
|
||||||
var success = string.Empty;
|
|
||||||
var successResult = Result<string, object>.Success(success);
|
|
||||||
|
|
||||||
var failure = new object();
|
|
||||||
var failedResult = Result<string, object>.Failure(failure);
|
|
||||||
|
|
||||||
var successOptional = successResult.ToOptional();
|
|
||||||
var failureOptional = failedResult.ToOptional();
|
|
||||||
|
|
||||||
successOptional.Should().NotBeNull();
|
|
||||||
failureOptional.Should().NotBeNull();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user