public static async Task WriteReadPrimitivesAsync(IAsyncBinaryReaderWriterSource source, bool littleEndian)
        {
            await using (source)
            {
                const short   value16 = 42;
                const int     value32 = int.MaxValue;
                const long    value64 = long.MaxValue;
                const decimal valueM  = 42M;

                var writer = source.CreateWriter();
                await writer.WriteInt16Async(value16, littleEndian);

                await writer.WriteInt32Async(value32, littleEndian);

                await writer.WriteInt64Async(value64, littleEndian);

                await writer.WriteAsync(valueM);

                var reader = source.CreateReader();
                Equal(value16, await reader.ReadInt16Async(littleEndian));
                Equal(value32, await reader.ReadInt32Async(littleEndian));
                Equal(value64, await reader.ReadInt64Async(littleEndian));
                Equal(valueM, await reader.ReadAsync <decimal>());
            }
        }
        public static async Task WriteReadStringAsync(IAsyncBinaryReaderWriterSource source, Encoding encoding, StringLengthEncoding?lengthFormat)
        {
            await using (source)
            {
                const string value  = "Hello, world!&*(@&*(fghjwgfwffgw ������, ���!";
                var          writer = source.CreateWriter();
                await writer.WriteAsync(value.AsMemory(), encoding, lengthFormat);

                var reader = source.CreateReader();
                var result = await(lengthFormat is null ?
                                   reader.ReadStringAsync(encoding.GetByteCount(value), encoding) :
                                   reader.ReadStringAsync(lengthFormat.GetValueOrDefault(), encoding));
                Equal(value, result);
            }
        }
        public static async Task CopyFromStreamToStream(IAsyncBinaryReaderWriterSource source)
        {
            await using (source)
            {
                var content = new byte[] { 1, 2, 3 };
                using var sourceStream = new MemoryStream(content, false);
                var writer = source.CreateWriter();
                await writer.CopyFromAsync(sourceStream);

                if (source is PipeSource pipe)
                {
                    await pipe.CompleteWriterAsync();
                }

                var reader = source.CreateReader();
                using var destStream = new MemoryStream(256);
                await reader.CopyToAsync(destStream);

                Equal(content, destStream.ToArray());
            }
        }
        public static async Task WriteReadPrimitivesAsync(IAsyncBinaryReaderWriterSource source, bool littleEndian, Encoding encoding)
        {
            await using (source)
            {
                const byte    value8   = 254;
                const short   value16  = 42;
                const int     value32  = int.MaxValue;
                const long    value64  = long.MaxValue;
                const decimal valueM   = 42M;
                const float   valueF   = 56.6F;
                const double  valueD   = 67.7D;
                var           valueG   = Guid.NewGuid();
                var           valueDT  = DateTime.Now;
                var           valueDTO = DateTimeOffset.Now;
                var           valueT   = TimeSpan.FromMilliseconds(1024);

                var writer = source.CreateWriter();
                await writer.WriteInt16Async(value16, littleEndian);

                await writer.WriteInt32Async(value32, littleEndian);

                await writer.WriteInt64Async(value64, littleEndian);

                await writer.WriteAsync(valueM);

                var encodingContext = new EncodingContext(encoding, true);
                await writer.WriteByteAsync(value8, StringLengthEncoding.Plain, encodingContext, provider : InvariantCulture);

                await writer.WriteInt16Async(value16, StringLengthEncoding.Compressed, encodingContext, provider : InvariantCulture);

                await writer.WriteInt32Async(value32, StringLengthEncoding.Plain, encodingContext, provider : InvariantCulture);

                await writer.WriteInt64Async(value64, StringLengthEncoding.PlainBigEndian, encodingContext, provider : InvariantCulture);

                await writer.WriteDecimalAsync(valueM, StringLengthEncoding.PlainLittleEndian, encodingContext, provider : InvariantCulture);

                await writer.WriteSingleAsync(valueF, StringLengthEncoding.Plain, encodingContext, provider : InvariantCulture);

                await writer.WriteDoubleAsync(valueD, StringLengthEncoding.Plain, encodingContext, provider : InvariantCulture);

                await writer.WriteGuidAsync(valueG, StringLengthEncoding.Plain, encodingContext);

                await writer.WriteGuidAsync(valueG, StringLengthEncoding.Plain, encodingContext, "X");

                await writer.WriteDateTimeAsync(valueDT, StringLengthEncoding.Plain, encodingContext, format : "O", provider : InvariantCulture);

                await writer.WriteDateTimeOffsetAsync(valueDTO, StringLengthEncoding.Plain, encodingContext, format : "O", provider : InvariantCulture);

                await writer.WriteDateTimeAsync(valueDT, StringLengthEncoding.Plain, encodingContext, format : "O", provider : InvariantCulture);

                await writer.WriteDateTimeOffsetAsync(valueDTO, StringLengthEncoding.Plain, encodingContext, format : "O", provider : InvariantCulture);

                await writer.WriteTimeSpanAsync(valueT, StringLengthEncoding.Plain, encodingContext);

                await writer.WriteTimeSpanAsync(valueT, StringLengthEncoding.Plain, encodingContext, "G", InvariantCulture);

                var reader = source.CreateReader();
                Equal(value16, await reader.ReadInt16Async(littleEndian));
                Equal(value32, await reader.ReadInt32Async(littleEndian));
                Equal(value64, await reader.ReadInt64Async(littleEndian));
                Equal(valueM, await reader.ReadAsync <decimal>());
                var decodingContext = new DecodingContext(encoding, true);
                Equal(value8, await reader.ReadByteAsync(StringLengthEncoding.Plain, decodingContext, provider: InvariantCulture));
                Equal(value16, await reader.ReadInt16Async(StringLengthEncoding.Compressed, decodingContext, provider: InvariantCulture));
                Equal(value32, await reader.ReadInt32Async(StringLengthEncoding.Plain, decodingContext, provider: InvariantCulture));
                Equal(value64, await reader.ReadInt64Async(StringLengthEncoding.PlainBigEndian, decodingContext, provider: InvariantCulture));
                Equal(valueM, await reader.ReadDecimalAsync(StringLengthEncoding.PlainLittleEndian, decodingContext, provider: InvariantCulture));
                Equal(valueF, await reader.ReadSingleAsync(StringLengthEncoding.Plain, decodingContext, provider: InvariantCulture));
                Equal(valueD, await reader.ReadDoubleAsync(StringLengthEncoding.Plain, decodingContext, provider: InvariantCulture));
                Equal(valueG, await reader.ReadGuidAsync(StringLengthEncoding.Plain, decodingContext));
                Equal(valueG, await reader.ReadGuidAsync(StringLengthEncoding.Plain, decodingContext, "X"));
                Equal(valueDT, await reader.ReadDateTimeAsync(StringLengthEncoding.Plain, decodingContext, style: DateTimeStyles.RoundtripKind, provider: InvariantCulture));
                Equal(valueDTO, await reader.ReadDateTimeOffsetAsync(StringLengthEncoding.Plain, decodingContext, style: DateTimeStyles.RoundtripKind, provider: InvariantCulture));
                Equal(valueDT, await reader.ReadDateTimeAsync(StringLengthEncoding.Plain, decodingContext, new[] { "O" }, style: DateTimeStyles.RoundtripKind, provider: InvariantCulture));
                Equal(valueDTO, await reader.ReadDateTimeOffsetAsync(StringLengthEncoding.Plain, decodingContext, new[] { "O" }, style: DateTimeStyles.RoundtripKind, provider: InvariantCulture));
                Equal(valueT, await reader.ReadTimeSpanAsync(StringLengthEncoding.Plain, decodingContext, InvariantCulture));
                Equal(valueT, await reader.ReadTimeSpanAsync(StringLengthEncoding.Plain, decodingContext, new[] { "G" }, TimeSpanStyles.None, InvariantCulture));
            }
        }