Skip to content
Open
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
42 changes: 23 additions & 19 deletions Generator/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,23 @@ string GetContent(bool isStruct, int i) {
var genericArgs = Range(0, i).Select(e => $"T{e}").ToList();
var genericArg = genericArgs.Joined(", ");
var sb = new StringBuilder();
const string invalidIndexException = "throw InvalidIndexException(_index)";

sb.Append(@$"using System;
sb.Append(@$"#nullable enable
using System;
using System.Diagnostics.CodeAnalysis;
using static OneOf.Functions;

namespace OneOf
{{
public {IfStruct("readonly struct", "class")} {className}<{genericArg}> : IOneOf
{{
{RangeJoined(@"
", j => $"readonly T{j} _value{j};")}
", j => $"readonly T{j} _value{j}{IfStruct("", " = default!")};")}
readonly int _index;

{IfStruct( // constructor
$@"OneOf(int index, {RangeJoined(", ", j => $"T{j} value{j} = default")})
$@"OneOf(int index, {RangeJoined(", ", j => $"T{j} value{j} = default!")})
{{
_index = index;
{RangeJoined(@"
Expand All @@ -62,17 +65,17 @@ namespace OneOf
{{
{RangeJoined($@"
", j => $"case {j}: _value{j} = input.AsT{j}; break;")}
default: throw new InvalidOperationException();
default: {invalidIndexException};
}}
}}"
)}

public object Value =>
public object? Value =>
_index switch
{{
{RangeJoined(@"
", j => $"{j} => _value{j},")}
_ => throw new InvalidOperationException()
_ => {invalidIndexException}
}};

public int Index => _index;
Expand All @@ -97,7 +100,7 @@ public void Switch({RangeJoined(", ", e => $"Action<T{e}> f{e}")})
f{j}(_value{j});
return;
}}")}
throw new InvalidOperationException();
{invalidIndexException};
}}

public TResult Match<TResult>({RangeJoined(", ", e => $"Func<T{e}, TResult> f{e}")})
Expand All @@ -107,7 +110,7 @@ public TResult Match<TResult>({RangeJoined(", ", e => $"Func<T{e}, TResult> f{e}
{{
return f{j}(_value{j});
}}")}
throw new InvalidOperationException();
{invalidIndexException};
}}

{IfStruct(genericArgs.Joined(@"
Expand All @@ -132,7 +135,7 @@ public TResult Match<TResult>({RangeJoined(", ", e => $"Func<T{e}, TResult> f{e}
x == bindToType ?
$"{k} => mapFunc(As{x})," :
$"{k} => As{x},")}
_ => throw new InvalidOperationException()
_ => {invalidIndexException}
}};
}}";
}))}
Expand All @@ -145,17 +148,21 @@ public TResult Match<TResult>({RangeJoined(", ", e => $"Func<T{e}, TResult> f{e}
var genericArgWithSkip = Range(0, i).ExceptSingle(j).Joined(", ", e => $"T{e}");
var remainderType = i == 2 ? genericArgWithSkip : $"OneOf<{genericArgWithSkip}>";
return $@"
public bool TryPickT{j}(out T{j} value, out {remainderType} remainder)
#if NET
public bool TryPickT{j}([NotNullWhen(true)] out T{j}? value, {(i == 2 ? "[NotNullWhen(false)] " : "")}out {remainderType}{(i == 2 ? "?" : "")} remainder)
#else
public bool TryPickT{j}(out T{j}? value, out {remainderType}{(i == 2 ? "?" : "")} remainder)
#endif
{{
value = IsT{j} ? AsT{j} : default;
remainder = _index switch
{{
{RangeJoined(@"
", k =>
k == j ?
$"{k} => default," :
$"{k} => AsT{k},")}
_ => throw new InvalidOperationException()
k == j ?
$"{k} => default," :
$"{k} => AsT{k},")}
_ => {invalidIndexException}
}};
return this.IsT{j};
}}";
Expand All @@ -173,7 +180,7 @@ bool Equals({className}<{genericArg}> other) =>
_ => false
}};

public override bool Equals(object obj)
public override bool Equals(object? obj)
{{
if (ReferenceEquals(null, obj))
{{
Expand Down Expand Up @@ -216,16 +223,13 @@ public override int GetHashCode()
return sb.ToString();
}

public static class Extensions {
internal static class Extensions {
public static string Joined<T>(this IEnumerable<T> source, string delimiter, Func<T, string>? selector = null) {
if (source == null) { return ""; }
if (selector == null) { return string.Join(delimiter, source); }
return string.Join(delimiter, source.Select(selector));
}
public static string Joined<T>(this IEnumerable<T> source, string delimiter, Func<T, int, string> selector) {
if (source == null) { return ""; }
return string.Join(delimiter, source.Select(selector));
}
public static IEnumerable<T> ExceptSingle<T>(this IEnumerable<T> source, T single) => source.Except(Repeat(single, 1));
public static void AppendLineTo(this string? s, StringBuilder sb) => sb.AppendLine(s);
}
11 changes: 0 additions & 11 deletions OneOf.Extended/Functions.cs

This file was deleted.

6 changes: 6 additions & 0 deletions OneOf.Extended/OneOf.Extended.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,10 @@
<ProjectReference Include="..\OneOf\OneOf.csproj" />
</ItemGroup>

<ItemGroup>
<Compile Include="..\OneOf\Functions.cs">
<Link>Functions.cs</Link>
</Compile>
</ItemGroup>

</Project>
Loading