~ruther/NosSmooth

38121333cae00bf16f9be6bd98a6ef5878437278 — František Boháček 3 years ago 1bbb749
feat: split inline generated deserialization into different methods
17 files changed, 257 insertions(+), 102 deletions(-)

M Core/NosSmooth.PacketSerializersGenerator/AttributeGenerators/PacketConditionalIndexAttributeGenerator.cs
M Core/NosSmooth.PacketSerializersGenerator/AttributeGenerators/PacketContextListAttributeGenerator.cs
M Core/NosSmooth.PacketSerializersGenerator/AttributeGenerators/PacketGreedyIndexAttributeGenerator.cs
M Core/NosSmooth.PacketSerializersGenerator/AttributeGenerators/PacketIndexAttributeGenerator.cs
M Core/NosSmooth.PacketSerializersGenerator/AttributeGenerators/PacketListIndexAttributeGenerator.cs
M Core/NosSmooth.PacketSerializersGenerator/Constants.cs
M Core/NosSmooth.PacketSerializersGenerator/ConverterDeserializationGenerator.cs
M Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/BasicInlineConverterGenerator.cs
M Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/BoolInlineConverterGenerator.cs
M Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/EnumInlineConverterGenerator.cs
M Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/FallbackInlineConverterGenerator.cs
M Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/IInlineConverterGenerator.cs
M Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/StringInlineConverterGenerator.cs
M Core/NosSmooth.PacketSerializersGenerator/InlineTypeConverterGenerator.cs
M Core/NosSmooth.PacketSerializersGenerator/NosSmooth.PacketSerializersGenerator.csproj
M Core/NosSmooth.PacketSerializersGenerator/PacketConverterGenerator.cs
M Core/NosSmooth.PacketSerializersGenerator/SourceGenerator.cs
M Core/NosSmooth.PacketSerializersGenerator/AttributeGenerators/PacketConditionalIndexAttributeGenerator.cs => Core/NosSmooth.PacketSerializersGenerator/AttributeGenerators/PacketConditionalIndexAttributeGenerator.cs +2 -2
@@ 218,7 218,7 @@ public class PacketConditionalIndexAttributeGenerator : IParameterGenerator
        }

        // serialize, check the error.
        _inlineTypeConverterGenerators.SerializeAndCheck(textWriter, packetInfo);
        _inlineTypeConverterGenerators.Serialize(textWriter, packetInfo);

        // pop inner separator level
        if (pushedLevel)


@@ 274,7 274,7 @@ public class PacketConditionalIndexAttributeGenerator : IParameterGenerator
            pushedLevel = true;
        }

        _inlineTypeConverterGenerators.DeserializeAndCheck(textWriter, packetInfo);
        generator.DeserializeAndCheck(parameter, packetInfo, _inlineTypeConverterGenerators);

        if (!parameter.Nullable)
        {

M Core/NosSmooth.PacketSerializersGenerator/AttributeGenerators/PacketContextListAttributeGenerator.cs => Core/NosSmooth.PacketSerializersGenerator/AttributeGenerators/PacketContextListAttributeGenerator.cs +2 -2
@@ 75,7 75,7 @@ public class PacketContextListAttributeGenerator : IParameterGenerator
        var innerSeparator = attribute.GetNamedValue<char>("InnerSeparator", '.');
        generator.PrepareLevel(innerSeparator);

        _inlineTypeConverterGenerators.SerializeAndCheck(textWriter, packetInfo);
        _inlineTypeConverterGenerators.Serialize(textWriter, packetInfo);
        generator.RemovePreparedLevel();
        generator.PopLevel();



@@ 115,7 115,7 @@ public class PacketContextListAttributeGenerator : IParameterGenerator
        var innerSeparator = attribute.GetNamedValue<char>("InnerSeparator", '.');
        generator.PrepareLevel(innerSeparator);

        _inlineTypeConverterGenerators.DeserializeAndCheck(textWriter, packetInfo);
        generator.DeserializeAndCheck(parameter, packetInfo, _inlineTypeConverterGenerators);
        generator.RemovePreparedLevel();
        generator.PopLevel();
        if (!parameter.Nullable)

M Core/NosSmooth.PacketSerializersGenerator/AttributeGenerators/PacketGreedyIndexAttributeGenerator.cs => Core/NosSmooth.PacketSerializersGenerator/AttributeGenerators/PacketGreedyIndexAttributeGenerator.cs +1 -1
@@ 82,7 82,7 @@ public class PacketGreedyIndexAttributeGenerator : IParameterGenerator
        }

        generator.SetReadToLast(); // Greedy
        _inlineTypeConverterGenerators.DeserializeAndCheck(textWriter, packetInfo);
        generator.DeserializeAndCheck(parameter, packetInfo, _inlineTypeConverterGenerators);

        if (!parameter.Nullable)
        {

M Core/NosSmooth.PacketSerializersGenerator/AttributeGenerators/PacketIndexAttributeGenerator.cs => Core/NosSmooth.PacketSerializersGenerator/AttributeGenerators/PacketIndexAttributeGenerator.cs +4 -4
@@ 77,7 77,7 @@ public class PacketIndexAttributeGenerator : IParameterGenerator
        }

        // serialize, check the error.
        _inlineTypeConverterGenerators.SerializeAndCheck(textWriter, packetInfo);
        _inlineTypeConverterGenerators.Serialize(textWriter, packetInfo);

        // pop inner separator level
        if (pushedLevel)


@@ 124,11 124,11 @@ public class PacketIndexAttributeGenerator : IParameterGenerator
            pushedLevel = true;
        }

        _inlineTypeConverterGenerators.DeserializeAndCheck(textWriter, packetInfo);

        generator.DeserializeAndCheck(parameter, packetInfo, _inlineTypeConverterGenerators);
        if (!parameter.Nullable)
        {
            generator.CheckNullError(parameter.GetNullableVariableName(), parameter.GetResultVariableName(), parameter.Name);
            generator.CheckNullError
                (parameter.GetNullableVariableName(), parameter.GetResultVariableName(), parameter.Name);
        }

        generator.AssignLocalVariable(parameter, false);

M Core/NosSmooth.PacketSerializersGenerator/AttributeGenerators/PacketListIndexAttributeGenerator.cs => Core/NosSmooth.PacketSerializersGenerator/AttributeGenerators/PacketListIndexAttributeGenerator.cs +2 -2
@@ 77,7 77,7 @@ public class PacketListIndexAttributeGenerator : IParameterGenerator
        var innerSeparator = attribute.GetNamedValue<char>("InnerSeparator", '.');
        generator.PrepareLevel(innerSeparator);

        _inlineTypeConverterGenerators.SerializeAndCheck(textWriter, packetInfo);
        _inlineTypeConverterGenerators.Serialize(textWriter, packetInfo);
        generator.RemovePreparedLevel();
        generator.PopLevel();



@@ 119,7 119,7 @@ public class PacketListIndexAttributeGenerator : IParameterGenerator
        var innerSeparator = attribute.GetNamedValue<char>("InnerSeparator", '.');
        generator.PrepareLevel(innerSeparator);

        _inlineTypeConverterGenerators.DeserializeAndCheck(textWriter, packetInfo);
        generator.DeserializeAndCheck(parameter, packetInfo, _inlineTypeConverterGenerators);
        generator.RemovePreparedLevel();
        generator.PopLevel();
        if (!parameter.Nullable)

M Core/NosSmooth.PacketSerializersGenerator/Constants.cs => Core/NosSmooth.PacketSerializersGenerator/Constants.cs +5 -0
@@ 20,4 20,9 @@ public class Constants
    /// Gets the full name of the packet attribute classes that are used for the generation.
    /// </summary>
    public static string PacketAttributesClassRegex => @"^NosSmooth\.Packets\.Attributes\.Packet.*";

    /// <summary>
    /// Gets the full name of helper class used for inline type converters.
    /// </summary>
    public static string HelperClass => "NosSmooth.Generated.HelperClass";
}
\ No newline at end of file

M Core/NosSmooth.PacketSerializersGenerator/ConverterDeserializationGenerator.cs => Core/NosSmooth.PacketSerializersGenerator/ConverterDeserializationGenerator.cs +25 -0
@@ 178,4 178,29 @@ if ({nullableVariableName} is null) {{
        _textWriter.Indent--;
        _textWriter.WriteLine("}");
    }

    /// <summary>
    /// Call deserializer and check the result.
    /// </summary>
    /// <param name="parameter">The parameter.</param>
    /// <param name="packet">The packet.</param>
    /// <param name="inlineTypeConverter">The inline converter generator.</param>
    public void DeserializeAndCheck(ParameterInfo parameter, PacketInfo packet, InlineTypeConverterGenerator inlineTypeConverter)
    {
        _textWriter.WriteLine($"var {parameter.GetResultVariableName()} = ");
        inlineTypeConverter.CallDeserialize(_textWriter, packet);

        _textWriter.WriteLine($"if (!{parameter.GetResultVariableName()}.IsSuccess)");
        _textWriter.Indent++;
        _textWriter.WriteLine
        (
            $"return Result<{packet.Name}?>.FromError(new PacketParameterSerializerError(this, \"{parameter.Name}\", {parameter.GetResultVariableName()}), {parameter.GetResultVariableName()});"
        );
        _textWriter.Indent--;

        _textWriter.WriteLine
        (
            $"{parameter.GetNullableType()} {parameter.GetNullableVariableName()} = {parameter.GetResultVariableName()}.Entity;"
        );
    }
}
\ No newline at end of file

M Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/BasicInlineConverterGenerator.cs => Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/BasicInlineConverterGenerator.cs +33 -22
@@ 36,31 36,42 @@ public class BasicInlineConverterGenerator : IInlineConverterGenerator
    }

    /// <inheritdoc />
    public IError? GenerateDeserializerPart(IndentedTextWriter textWriter, PacketInfo packet)
    public IError? CallDeserialize(IndentedTextWriter textWriter, PacketInfo packet)
    {
        var parameter = packet.Parameters.Current;
        var type = parameter.Parameter.Type!.ToString();
        string isLastString = packet.Parameters.IsLast ? "true" : "false";
        textWriter.WriteMultiline
        (
            $@"
var {parameter.GetResultVariableName()} = stringEnumerator.GetNextToken();
var {parameter.GetErrorVariableName()} = CheckDeserializationResult({parameter.GetResultVariableName()}, ""{parameter.Name}"", stringEnumerator, {isLastString});
if ({parameter.GetErrorVariableName()} is not null)
        var type = parameter.Parameter.Type!.ToString().Trim('?');
        textWriter.WriteLine($"{Constants.HelperClass}.ParseBasic{type}(this, stringEnumerator);");
        return null;
    }

    /// <inheritdoc />
    public void GenerateHelperMethods(IndentedTextWriter textWriter)
    {
        foreach (var type in HandleTypes)
        {
            textWriter.WriteMultiline($@"
public static Result<{type}?> ParseBasic{type}(ITypeConverter typeConverter, PacketStringEnumerator stringEnumerator)
{{
    return Result<{packet.Name}?>.FromError({parameter.GetErrorVariableName()}, {parameter.GetResultVariableName()});
}}
{parameter.GetVariableName()} = default;
{parameter.GetNullableType()} {parameter.GetNullableVariableName()};
if ({parameter.GetResultVariableName()}.Entity.Token == ""-"") {{
    {parameter.GetNullableVariableName()} = null;
}}
else if (!{type}.TryParse({parameter.GetResultVariableName()}.Entity.Token, out {parameter.GetVariableName()})) {{
    return new PacketParameterSerializerError(this, ""{parameter.Name}"", {parameter.GetResultVariableName()}, $""Could not convert {{{parameter.GetResultVariableName()}.Entity.Token}} as {type} in inline converter"");
    var tokenResult = stringEnumerator.GetNextToken();
    if (!tokenResult.IsSuccess)
    {{
        return Result<{type}?>.FromError(tokenResult);
    }}

    var token = tokenResult.Entity.Token;
    if (token == ""-"")
    {{
        return Result<{type}?>.FromSuccess(null);
    }}

    if (!{type}.TryParse(token, out var val))
    {{
        return new CouldNotConvertError(typeConverter, token, ""Could not convert as {type} in inline converter"");
    }}

    return val;
}}
{parameter.GetNullableVariableName()} = {parameter.GetVariableName()};
"
        );
        return null;
");
        }
    }
}
\ No newline at end of file

M Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/BoolInlineConverterGenerator.cs => Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/BoolInlineConverterGenerator.cs +27 -3
@@ 41,10 41,11 @@ public class BoolInlineConverterGenerator : IInlineConverterGenerator
    }

    /// <inheritdoc />
    public IError? GenerateDeserializerPart(IndentedTextWriter textWriter, PacketInfo packet)
    public IError? CallDeserialize(IndentedTextWriter textWriter, PacketInfo packet)
    {
        var parameter = packet.Parameters.Current;
        string isLastString = packet.Parameters.IsLast ? "true" : "false";
        textWriter.WriteLine($"{Constants.HelperClass}.ParseBool(stringEnumerator);");
        /*string isLastString = packet.Parameters.IsLast ? "true" : "false";
        textWriter.WriteMultiline($@"
var {parameter.GetResultVariableName()} = stringEnumerator.GetNextToken();
var {parameter.GetErrorVariableName()} = CheckDeserializationResult({parameter.GetResultVariableName()}, ""{parameter.Name}"", stringEnumerator, {isLastString});


@@ 53,7 54,30 @@ if ({parameter.GetErrorVariableName()} is not null)
    return Result<{packet.Name}?>.FromError({parameter.GetErrorVariableName()}, {parameter.GetResultVariableName()});
}}
{parameter.GetNullableType()} {parameter.GetNullableVariableName()} = {parameter.GetResultVariableName()}.Entity.Token == ""1"" ? true : ({parameter.GetResultVariableName()}.Entity.Token == ""-"" ? null : false);
");
");*/
        return null;
    }

    /// <inheritdoc />
    public void GenerateHelperMethods(IndentedTextWriter textWriter)
    {
        textWriter.WriteLine(@"
public static Result<bool?> ParseBool(PacketStringEnumerator stringEnumerator)
{{
    var tokenResult = stringEnumerator.GetNextToken();
    if (!tokenResult.IsSuccess)
    {{
        return Result<bool?>.FromError(tokenResult);
    }}

    var token = tokenResult.Entity.Token;
    if (token == ""-"")
    {{
        return Result<bool?>.FromSuccess(null);
    }}

    return token == ""1"" ? true : false;
}}
");
    }
}
\ No newline at end of file

M Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/EnumInlineConverterGenerator.cs => Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/EnumInlineConverterGenerator.cs +54 -23
@@ 15,6 15,16 @@ namespace NosSmooth.PacketSerializersGenerator.InlineConverterGenerators;
/// <inheritdoc />
public class EnumInlineConverterGenerator : IInlineConverterGenerator
{
    private readonly List<ITypeSymbol> _enumTypes;

    /// <summary>
    /// Initializes a new instance of the <see cref="EnumInlineConverterGenerator"/> class.
    /// </summary>
    public EnumInlineConverterGenerator()
    {
        _enumTypes = new List<ITypeSymbol>();
    }

    /// <inheritdoc />
    public bool ShouldHandle(ParameterInfo parameter)
        => parameter.Type.TypeKind == TypeKind.Enum;


@@ 25,37 35,58 @@ public class EnumInlineConverterGenerator : IInlineConverterGenerator
        var parameter = packet.Parameters.Current;
        var underlyingType = ((INamedTypeSymbol)parameter.Type).EnumUnderlyingType!.ToString();
        textWriter.WriteLine
            ($"builder.Append((({underlyingType}?)obj.{parameter.Name}{(parameter.Nullable ? "?" : string.Empty)}).ToString() ?? \"-\");");
        (
            $"builder.Append((({underlyingType}?)obj.{parameter.Name}{(parameter.Nullable ? "?" : string.Empty)}).ToString() ?? \"-\");"
        );
        return null;
    }

    /// <inheritdoc />
    public IError? GenerateDeserializerPart(IndentedTextWriter textWriter, PacketInfo packet)
    public IError? CallDeserialize(IndentedTextWriter textWriter, PacketInfo packet)
    {
        var parameter = packet.Parameters.Current;
        var underlyingType = ((INamedTypeSymbol)parameter.Type).EnumUnderlyingType!.ToString();
        string isLastString = packet.Parameters.IsLast ? "true" : "false";
        textWriter.WriteMultiline
        (
            $@"
var {parameter.GetResultVariableName()} = stringEnumerator.GetNextToken();
var {parameter.GetErrorVariableName()} = CheckDeserializationResult({parameter.GetResultVariableName()}, ""{parameter.Name}"", stringEnumerator, {isLastString});
if ({parameter.GetErrorVariableName()} is not null)
        if (_enumTypes.All(x => x.ToString() != parameter.Type.ToString()))
        {
            _enumTypes.Add(parameter.Type);
        }

        textWriter.WriteLine
            ($"{Constants.HelperClass}.ParseEnum{parameter.GetActualType().Replace('.', '_')}(this, stringEnumerator);");
        return null;
    }

    /// <inheritdoc />
    public void GenerateHelperMethods(IndentedTextWriter textWriter)
    {
        foreach (var type in _enumTypes)
        {
            var underlyingType = ((INamedTypeSymbol)type).EnumUnderlyingType!.ToString();
            textWriter.WriteMultiline
            (
                $@"
public static Result<{type}?> ParseEnum{type.ToString().Replace('.', '_')}(ITypeConverter typeConverter, PacketStringEnumerator stringEnumerator)
{{
    return Result<{packet.Name}?>.FromError({parameter.GetErrorVariableName()}, {parameter.GetResultVariableName()});
}}
{parameter.GetVariableName()} = default;
{underlyingType} {parameter.GetVariableName()}Underlying = default;
{parameter.GetNullableType()} {parameter.GetNullableVariableName()};
if ({parameter.GetResultVariableName()}.Entity.Token == ""-"") {{
    {parameter.GetNullableVariableName()} = null;
}}
else if (!{underlyingType}.TryParse({parameter.GetResultVariableName()}.Entity.Token, out {parameter.GetVariableName()}Underlying)) {{
    return new PacketParameterSerializerError(this, ""{parameter.Name}"", {parameter.GetResultVariableName()}, $""Could not convert {{{parameter.GetResultVariableName()}.Entity.Token}} as {underlyingType} in inline converter"");
    var tokenResult = stringEnumerator.GetNextToken();
    if (!tokenResult.IsSuccess)
    {{
        return Result<{type}?>.FromError(tokenResult);
    }}

    var token = tokenResult.Entity.Token;
    if (token == ""-"")
    {{
        return Result<{type}?>.FromSuccess(null);
    }}

    if (!{underlyingType}.TryParse(token, out var val))
    {{
        return new CouldNotConvertError(typeConverter, token, ""Could not convert as {type} in inline converter"");
    }}

    return ({type}?)val;
}}
{parameter.GetNullableVariableName()} = ({parameter.GetNullableType()}){parameter.GetVariableName()}Underlying;
"
        );
        return null;
            );
        }
    }
}
\ No newline at end of file

M Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/FallbackInlineConverterGenerator.cs => Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/FallbackInlineConverterGenerator.cs +9 -21
@@ 24,33 24,21 @@ public class FallbackInlineConverterGenerator : IInlineConverterGenerator
    public IError? GenerateSerializerPart(IndentedTextWriter textWriter, PacketInfo packet)
    {
        var parameter = packet.Parameters.Current;
        textWriter.WriteMultiline
        (
            $@"
var {parameter.GetResultVariableName()} = _typeConverterRepository.Serialize<{parameter.GetActualType()}>(obj.{parameter.Name}, builder);
if (!{parameter.GetResultVariableName()}.IsSuccess)
{{
    return Result.FromError(new PacketParameterSerializerError(this, ""{parameter.Name}"", {parameter.GetResultVariableName()}), {parameter.GetResultVariableName()});
}}
"
        );
        textWriter.WriteLine($"_typeConverterRepository.Serialize<{parameter.GetActualType()}>(obj.{parameter.Name}, builder);");
        return null;
    }

    /// <inheritdoc />
    public IError? GenerateDeserializerPart(IndentedTextWriter textWriter, PacketInfo packet)
    public IError? CallDeserialize(IndentedTextWriter textWriter, PacketInfo packet)
    {
        var parameter = packet.Parameters.Current;
        string isLastString = packet.Parameters.IsLast ? "true" : "false";
        textWriter.WriteMultiline($@"
var {parameter.GetResultVariableName()} = _typeConverterRepository.Deserialize<{parameter.GetNullableType()}>(stringEnumerator);
var {parameter.GetErrorVariableName()} = CheckDeserializationResult({parameter.GetResultVariableName()}, ""{parameter.Name}"", stringEnumerator, {isLastString});
if ({parameter.GetErrorVariableName()} is not null)
{{
    return Result<{packet.Name}?>.FromError({parameter.GetErrorVariableName()}, {parameter.GetResultVariableName()});
}}
var {parameter.GetNullableVariableName()} = {parameter.GetResultVariableName()}.Entity;
");
        textWriter.WriteLine($"_typeConverterRepository.Deserialize<{parameter.GetNullableType()}>(stringEnumerator);");
        return null;
    }

    /// <inheritdoc />
    public void GenerateHelperMethods(IndentedTextWriter textWriter)
    {
        // ignore
    }
}
\ No newline at end of file

M Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/IInlineConverterGenerator.cs => Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/IInlineConverterGenerator.cs +13 -1
@@ 36,5 36,17 @@ public interface IInlineConverterGenerator
    /// <param name="textWriter">The text writer to write to.</param>
    /// <param name="packet">The packet.</param>
    /// <returns>An error, if any.</returns>
    public IError? GenerateDeserializerPart(IndentedTextWriter textWriter, PacketInfo packet);
    public IError? CallDeserialize(IndentedTextWriter textWriter, PacketInfo packet);

    /// <summary>
    /// Generate helper methods to HelperClass.
    /// </summary>
    /// <remarks>
    /// These will be added to class <see cref="Constants.HelperClass"/>.
    /// This will be called after calling <see cref="CallDeserialize"/> and
    /// <see cref="GenerateSerializerPart"/> for all packets and parameters.
    /// The converter can group information it needs for the generations that way.
    /// </remarks>
    /// <param name="textWriter">The text writer to append full methods to.</param>
    public void GenerateHelperMethods(IndentedTextWriter textWriter);
}
\ No newline at end of file

M Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/StringInlineConverterGenerator.cs => Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/StringInlineConverterGenerator.cs +26 -5
@@ 27,11 27,12 @@ public class StringInlineConverterGenerator : IInlineConverterGenerator
    }

    /// <inheritdoc />
    public IError? GenerateDeserializerPart(IndentedTextWriter textWriter, PacketInfo packet)
    public IError? CallDeserialize(IndentedTextWriter textWriter, PacketInfo packet)
    {
        var parameter = packet.Parameters.Current;
        string isLastString = packet.Parameters.IsLast ? "true" : "false";
        textWriter.WriteMultiline($@"
        // var parameter = packet.Parameters.Current;
        // string isLastString = packet.Parameters.IsLast ? "true" : "false";
        textWriter.WriteLine($"{Constants.HelperClass}.ParseString(stringEnumerator);");
        /*textWriter.WriteMultiline($@"
var {parameter.GetResultVariableName()} = stringEnumerator.GetNextToken();
var {parameter.GetErrorVariableName()} = CheckDeserializationResult({parameter.GetResultVariableName()}, ""{parameter.Name}"", stringEnumerator, {isLastString});
if ({parameter.GetErrorVariableName()} is not null)


@@ 39,7 40,27 @@ if ({parameter.GetErrorVariableName()} is not null)
    return Result<{packet.Name}?>.FromError({parameter.GetErrorVariableName()}, {parameter.GetResultVariableName()});
}}
var {parameter.GetNullableVariableName()} = {parameter.GetResultVariableName()}.Entity.Token == ""-"" ? null : {parameter.GetResultVariableName()}.Entity.Token;
");
");*/
        return null;
    }

    /// <inheritdoc />
    public void GenerateHelperMethods(IndentedTextWriter textWriter)
    {
        textWriter.WriteLine
        (
            @"
public static Result<string?> ParseString(PacketStringEnumerator stringEnumerator)
{{
    var tokenResult = stringEnumerator.GetNextToken();
    if (!tokenResult.IsSuccess)
    {{
        return Result<string?>.FromError(tokenResult);
    }}

    return tokenResult.Entity.Token;
}}
"
        );
    }
}
\ No newline at end of file

M Core/NosSmooth.PacketSerializersGenerator/InlineTypeConverterGenerator.cs => Core/NosSmooth.PacketSerializersGenerator/InlineTypeConverterGenerator.cs +4 -4
@@ 37,7 37,7 @@ public class InlineTypeConverterGenerator
    /// <param name="textWriter">The text writer.</param>
    /// <param name="packet">The packet.</param>
    /// <returns>An error, if any.</returns>
    public IError? DeserializeAndCheck(IndentedTextWriter textWriter, PacketInfo packet)
    public IError? CallDeserialize(IndentedTextWriter textWriter, PacketInfo packet)
    {
        var shouldGenerateInline = packet.GenerateAttribute.GetIndexedValue<bool>(0);
        if (shouldGenerateInline)


@@ 46,12 46,12 @@ public class InlineTypeConverterGenerator
            {
                if (generator.ShouldHandle(packet.Parameters.Current))
                {
                    return generator.GenerateDeserializerPart(textWriter, packet);
                    return generator.CallDeserialize(textWriter, packet);
                }
            }
        }

        return _fallbackInlineConverterGenerator.GenerateDeserializerPart(textWriter, packet);
        return _fallbackInlineConverterGenerator.CallDeserialize(textWriter, packet);
    }

    /// <summary>


@@ 60,7 60,7 @@ public class InlineTypeConverterGenerator
    /// <param name="textWriter">The text writer.</param>
    /// <param name="packet">The packet.</param>
    /// <returns>An error, if any.</returns>
    public IError? SerializeAndCheck(IndentedTextWriter textWriter, PacketInfo packet)
    public IError? Serialize(IndentedTextWriter textWriter, PacketInfo packet)
    {
        var shouldGenerateInline = packet.GenerateAttribute.GetIndexedValue<bool>(0);
        if (shouldGenerateInline)

M Core/NosSmooth.PacketSerializersGenerator/NosSmooth.PacketSerializersGenerator.csproj => Core/NosSmooth.PacketSerializersGenerator/NosSmooth.PacketSerializersGenerator.csproj +4 -0
@@ 19,4 19,8 @@
        <EmbeddedResource Include="$(PkgRemora_Results)\lib\netstandard2.0\*.dll" Visible="false" />
    </ItemGroup>

    <ItemGroup>
      <Folder Include="HelperClassGenerators" />
    </ItemGroup>

</Project>

M Core/NosSmooth.PacketSerializersGenerator/PacketConverterGenerator.cs => Core/NosSmooth.PacketSerializersGenerator/PacketConverterGenerator.cs +0 -10
@@ 112,16 112,6 @@ public override Result<{_packetInfo.Name}?> Deserialize(PacketStringEnumerator s
        (
            $@"
    }}

private IResultError? CheckDeserializationResult<T>(Result<T> result, string property, PacketStringEnumerator stringEnumerator, bool last = false)
{{
    if (!result.IsSuccess)
    {{
        return new PacketParameterSerializerError(this, property, result);
    }}

    return null;
}}
}}"
        );
        return null;

M Core/NosSmooth.PacketSerializersGenerator/SourceGenerator.cs => Core/NosSmooth.PacketSerializersGenerator/SourceGenerator.cs +46 -2
@@ 32,7 32,7 @@ public class SourceGenerator : ISourceGenerator
    /// </summary>
    public SourceGenerator()
    {
        var typeGenerators = new List<IInlineConverterGenerator>
        _typeConverterGenerator = new List<IInlineConverterGenerator>
        (
            new IInlineConverterGenerator[]
            {


@@ 43,7 43,7 @@ public class SourceGenerator : ISourceGenerator
            }
        );

        var inlineTypeConverter = new InlineTypeConverterGenerator(typeGenerators);
        var inlineTypeConverter = new InlineTypeConverterGenerator(_typeConverterGenerator);

        _generators = new List<IParameterGenerator>
        (


@@ 59,6 59,7 @@ public class SourceGenerator : ISourceGenerator
    }

    private readonly List<IParameterGenerator> _generators;
    private readonly List<IInlineConverterGenerator> _typeConverterGenerator;

    /// <inheritdoc />
    public void Initialize(GeneratorInitializationContext context)


@@ 129,8 130,51 @@ public class SourceGenerator : ISourceGenerator
                    $"{packetRecord.GetPrefix()}.{packetRecord.Identifier.NormalizeWhitespace().ToFullString()}Converter.g.cs",
                    stringWriter.GetStringBuilder().ToString()
                );
                File.WriteAllText
                (
                    $"/tmp/{packetRecord.GetPrefix()}.{packetRecord.Identifier.NormalizeWhitespace().ToFullString()}Converter.g.cs",
                    stringWriter.GetStringBuilder().ToString()
                );
            }
        }

        var helperClass = GenerateHelperMethods();
        context.AddSource
        (
            $"HelperClass.g.cs",
            helperClass
        );
        File.WriteAllText
        (
            $"/tmp/HelperClass.g.cs",
            helperClass
        );
    }

    private string GenerateHelperMethods()
    {
        using var stringWriter = new StringWriter();
        using var writer = new IndentedTextWriter(stringWriter, "    ");
        writer.WriteMultiline(@"// <auto-generated/>
#nullable enable
#pragma warning disable 1591

using NosSmooth.Packets.Converters;
using NosSmooth.Packets.Errors;
using NosSmooth.Packets;
using Remora.Results;

namespace NosSmooth.Generated;

internal static class HelperClass
{
");
        foreach (var inlineHelperGenerator in _typeConverterGenerator)
        {
            inlineHelperGenerator.GenerateHelperMethods(writer);
        }
        writer.WriteLine("}");
        return stringWriter.GetStringBuilder().ToString();
    }

    private IError? GeneratePacketSerializer

Do not follow this link