private async Task <DeleteResult> TombstoneInternal(TombstoneReq request, UserCredentials userCredentials,
                                                            CancellationToken cancellationToken)
        {
            var result = await _client.TombstoneAsync(request, RequestMetadata.Create(userCredentials),
                                                      cancellationToken : cancellationToken);

            return(new DeleteResult(new Position(result.Position.CommitPosition, result.Position.PreparePosition)));
        }
        private async IAsyncEnumerable <ResolvedEvent> ReadInternal(
            ReadReq request,
            UserCredentials userCredentials,
            [EnumeratorCancellation] CancellationToken cancellationToken)
        {
            if (request.Options.CountOptionCase == ReadReq.Types.Options.CountOptionOneofCase.Count &&
                request.Options.Count <= 0)
            {
                throw new ArgumentOutOfRangeException("count");
            }

            if (request.Options.Filter == null)
            {
                request.Options.NoFilter = new ReadReq.Types.Empty();
            }

            request.Options.UuidOption = new ReadReq.Types.Options.Types.UUIDOption
            {
                Structured = new ReadReq.Types.Empty()
            };

            using var call = _client.Read(
                      request, RequestMetadata.Create(userCredentials),
                      cancellationToken: cancellationToken);

            await foreach (var e in call.ResponseStream
                           .ReadAllAsync(cancellationToken)
                           .Select(ConvertToResolvedEvent)
                           .WithCancellation(cancellationToken)
                           .ConfigureAwait(false))
            {
                yield return(e);
            }

            ResolvedEvent ConvertToResolvedEvent(ReadResp response) =>
            new ResolvedEvent(
                ConvertToEventRecord(response.Event.Event),
                ConvertToEventRecord(response.Event.Link),
                response.Event.PositionCase switch {
                ReadResp.Types.ReadEvent.PositionOneofCase.CommitPosition => new Position(
                    response.Event.CommitPosition, 0).ToInt64().commitPosition,
                ReadResp.Types.ReadEvent.PositionOneofCase.NoPosition => null,
                _ => throw new InvalidOperationException()
            });
        private async Task <WriteResult> AppendToStreamInternal(
            AppendReq header,
            IEnumerable <EventData> eventData,
            UserCredentials userCredentials,
            CancellationToken cancellationToken)
        {
            using var call = _client.Append(RequestMetadata.Create(userCredentials),
                                            cancellationToken: cancellationToken);

            await call.RequestStream.WriteAsync(header);

            foreach (var e in eventData)
            {
                await call.RequestStream.WriteAsync(new AppendReq {
                    ProposedMessage = new AppendReq.Types.ProposedMessage {
                        Id = new Streams.UUID {
                            String = e.EventId.ToString("n")
                        },
                        Data           = ByteString.CopyFrom(e.Data),
                        CustomMetadata = ByteString.CopyFrom(e.Metadata),
                        Metadata       =
                        {
                            { Constants.Metadata.Type,   e.Type                                 },
                            { Constants.Metadata.IsJson, e.IsJson.ToString().ToLowerInvariant() }
                        }
                    }
                });
            }

            await call.RequestStream.CompleteAsync();

            var response = await call.ResponseAsync;

            return(new WriteResult(
                       response.CurrentRevisionOptionsCase == AppendResp.CurrentRevisionOptionsOneofCase.NoStream
                                        ? AnyStreamRevision.NoStream.ToInt64()
                                        : new StreamRevision(response.CurrentRevision).ToInt64(),
                       response.PositionOptionsCase == AppendResp.PositionOptionsOneofCase.Position
                                        ? new Position(response.Position.CommitPosition, response.Position.PreparePosition)
                                        : default));
        }