feat: add OneOf
This commit is contained in:
parent
c39fdd86ec
commit
cdcfd671f0
109
Base/Structures/OneOf.cs
Normal file
109
Base/Structures/OneOf.cs
Normal file
|
@ -0,0 +1,109 @@
|
|||
namespace FruityFoundation.Base.Structures;
|
||||
|
||||
public class OneOf<T1, T2>
|
||||
{
|
||||
private Maybe<T1> _itemOne { get; }
|
||||
private Maybe<T2> _itemTwo { get; }
|
||||
|
||||
public T1 ItemOne => _itemOne.OrThrow($"{nameof(ItemOne)} must have a value in order to be accessed");
|
||||
public T2 ItemTwo => _itemTwo.OrThrow($"{nameof(ItemTwo)} must have a value in order to be accessed");
|
||||
|
||||
public object? RawItem
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_itemOne.HasValue)
|
||||
return _itemOne.Value;
|
||||
else if (_itemTwo.HasValue)
|
||||
return _itemTwo.Value;
|
||||
|
||||
// This is specifically a null and not a Maybe<object> so we can pattern match on it
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public T Map<T>(Func<T1, T> itemOneMap, Func<T2, T> itemTwoMap)
|
||||
{
|
||||
if (_itemOne.Try(out var itemOne))
|
||||
return itemOneMap(itemOne);
|
||||
else if (_itemTwo.Try(out var itemTwo))
|
||||
return itemTwoMap(itemTwo);
|
||||
|
||||
throw new NotImplementedException("Map condition not handled");
|
||||
}
|
||||
|
||||
private OneOf(Maybe<T1> one, Maybe<T2> two)
|
||||
{
|
||||
_itemOne = one;
|
||||
_itemTwo = two;
|
||||
}
|
||||
|
||||
public static implicit operator OneOf<T1, T2>(T1 oneOf) => new(oneOf, default);
|
||||
public static implicit operator OneOf<T1, T2>(T2 oneOf) => new(default, oneOf);
|
||||
}
|
||||
|
||||
public class OneOf<T1, T2, T3>
|
||||
{
|
||||
private Maybe<T1> _itemOne { get; }
|
||||
private Maybe<T2> _itemTwo { get; }
|
||||
private Maybe<T3> _itemThree { get; }
|
||||
|
||||
public T1 ItemOne => _itemOne.OrThrow($"{nameof(ItemOne)} must have a value in order to be accessed");
|
||||
public T2 ItemTwo => _itemTwo.OrThrow($"{nameof(ItemTwo)} must have a value in order to be accessed");
|
||||
public T3 ItemThree => _itemThree.OrThrow($"{nameof(ItemThree)} must have a value in order to be accessed");
|
||||
|
||||
public object? RawItem
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_itemOne.HasValue)
|
||||
return _itemOne.Value;
|
||||
else if (_itemTwo.HasValue)
|
||||
return _itemTwo.Value;
|
||||
else if (_itemThree.HasValue)
|
||||
return _itemThree.Value;
|
||||
|
||||
// This is specifically a null and not a Maybe<object> so we can pattern match on it
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public T Map<T>(Func<T1, T> itemOneMap, Func<T2, T> itemTwoMap, Func<T3, T> itemThreeMap)
|
||||
{
|
||||
if (_itemOne.Try(out var itemOne))
|
||||
return itemOneMap(itemOne);
|
||||
else if (_itemTwo.Try(out var itemTwo))
|
||||
return itemTwoMap(itemTwo);
|
||||
else if (_itemThree.Try(out var itemThree))
|
||||
return itemThreeMap(itemThree);
|
||||
|
||||
throw new NotImplementedException("Map condition not handled");
|
||||
}
|
||||
|
||||
public Type? ItemType
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_itemOne.HasValue)
|
||||
return typeof(T1);
|
||||
else if (_itemTwo.HasValue)
|
||||
return typeof(T2);
|
||||
else if (_itemThree.HasValue)
|
||||
return typeof(T3);
|
||||
|
||||
// This is specifically a null and not a Maybe<Type> so we can pattern match on it
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private OneOf(Maybe<T1> one, Maybe<T2> two, Maybe<T3> three)
|
||||
{
|
||||
_itemOne = one;
|
||||
_itemTwo = two;
|
||||
_itemThree = three;
|
||||
}
|
||||
|
||||
public static implicit operator OneOf<T1, T2, T3>(T1 oneOf) => new(oneOf, default, default);
|
||||
public static implicit operator OneOf<T1, T2, T3>(T2 oneOf) => new(default, oneOf, default);
|
||||
public static implicit operator OneOf<T1, T2, T3>(T3 oneOf) => new(default, default, oneOf);
|
||||
}
|
Loading…
Reference in New Issue
Block a user