~ruther/NosSmooth

998ce1e07772dab0c289f8dd661c649dad9b69df — František Boháček 2 years ago 917d85a
feat(packets): add possibility to increment read tokens for arrays using capture and increment read tokens
M Packets/NosSmooth.PacketSerializer.Abstractions/PacketStringEnumerator.cs => Packets/NosSmooth.PacketSerializer.Abstractions/PacketStringEnumerator.cs +39 -0
@@ 54,6 54,43 @@ public ref struct PacketStringEnumerator
    }

    /// <summary>
    /// Capture current read tokens number.
    /// </summary>
    /// <remarks>
    /// Usable for lists that may have indeterminate separators (same multiple separators).
    /// The list converter may capture read tokens before reading an element and increment after token is read.
    /// </remarks>
    public void CaptureReadTokens()
    {
        _currentLevel.CapturedTokensRead = _currentLevel.TokensRead;
    }

    /// <summary>
    /// Increment read tokens from the captured state taht was captured using <see cref="CaptureReadTokens"/>.
    /// </summary>
    /// <remarks>
    /// Usable for lists that may have indeterminate separators (same multiple separators).
    /// The list converter may capture read tokens before reading an element and increment after token is read.
    /// </remarks>
    /// <exception cref="InvalidOperationException">Thrown in case <see cref="CaptureReadTokens"/> was not called before.</exception>
    public void IncrementReadTokens()
    {
        if (_currentLevel.CapturedTokensRead is null)
        {
            throw new InvalidOperationException
                ("The read tokens cannot be incremented as CaptureReadTokens was not called.");
        }

        _currentLevel.TokensRead = _currentLevel.CapturedTokensRead.Value + 1;
        _currentLevel.CapturedTokensRead = null;

        if (_currentLevel.TokensRead >= _currentLevel.MaxTokens)
        {
            _currentLevel.ReachedEnd = true;
        }
    }

    /// <summary>
    /// Sets that the next token should be read to the last entry in the level.
    /// </summary>
    public void SetReadToLast()


@@ 367,5 404,7 @@ public ref struct PacketStringEnumerator
        public bool? ReachedEnd { get; set; }

        public (char Separator, uint? MaxTokens)? PreparedLevel { get; set; }

        public uint? CapturedTokensRead { get; set; }
    }
}
\ No newline at end of file

M Packets/NosSmooth.PacketSerializer/Converters/Special/Converters/ListStringConverter.cs => Packets/NosSmooth.PacketSerializer/Converters/Special/Converters/ListStringConverter.cs +2 -1
@@ 26,7 26,6 @@ public class ListStringConverter<TGeneric> : BaseStringConverter<IReadOnlyList<T
    public ListStringConverter(IStringSerializer serializer)
    {
        _serializer = serializer;

    }

    /// <inheritdoc />


@@ 63,6 62,7 @@ public class ListStringConverter<TGeneric> : BaseStringConverter<IReadOnlyList<T

        while (!(stringEnumerator.IsOnLastToken() ?? false))
        {
            stringEnumerator.CaptureReadTokens();
            if (!stringEnumerator.PushPreparedLevel())
            {
                return new ArgumentInvalidError(nameof(stringEnumerator), "The string enumerator has to have a prepared level for all lists.");


@@ 79,6 79,7 @@ public class ListStringConverter<TGeneric> : BaseStringConverter<IReadOnlyList<T
            }

            stringEnumerator.PopLevel();
            stringEnumerator.IncrementReadTokens();
            if (!result.IsSuccess)
            {
                return Result<IReadOnlyList<TGeneric>?>.FromError(new ListSerializerError(result, list.Count), result);

M Packets/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/ListInlineConverterGenerator.cs => Packets/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/ListInlineConverterGenerator.cs +2 -0
@@ 112,6 112,7 @@ public static Result<IReadOnlyList<{type.GetActualType()}>> {GetMethodName(type,

    while (!(stringEnumerator.IsOnLastToken() ?? false))
    {{
        stringEnumerator.CaptureReadTokens();
        if (!stringEnumerator.PushPreparedLevel())
        {{
            return new ArgumentInvalidError(nameof(stringEnumerator), ""The string enumerator has to have a prepared level for all lists."");


@@ 132,6 133,7 @@ public static Result<IReadOnlyList<{type.GetActualType()}>> {GetMethodName(type,
        }}

        stringEnumerator.PopLevel();
        stringEnumerator.IncrementReadTokens();
        if (!result.IsSuccess)
        {{
            return Result<IReadOnlyList<{type}>>.FromError(new ListSerializerError(result, data.Count), result);

Do not follow this link