1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

use crate::generated::ydb::{table, discovery};
use table::*;
use discovery::*;
use thiserror::Error;

#[derive(Error, Debug)]
pub enum ExtractResultError {
    #[error("Empty body of response")]
    Empty,
    #[error("Cannot decode result: {0}")]
    Decode(#[from] prost::DecodeError),
}

/// The trait to invoke payload result from response. See examples in [`crate::client`]
pub trait YdbResponseWithResult {
    type Result;
    fn result(&self) -> Result<Self::Result,ExtractResultError>;
}


macro_rules! payloaded {
    ($($x:ty : $p:ty,)+) => {$(
        impl YdbResponseWithResult for $x {
            type Result = $p;
            fn result(&self) -> Result<Self::Result, ExtractResultError> {
                use prost::Message;
                use ExtractResultError::*;
                let operation = self.operation.as_ref().ok_or(Empty)?;
                let bytes = operation
                    .result.as_ref().ok_or(Empty)?
                    .value.as_slice();
                Message::decode(bytes).map_err(|e|Decode(e))
            }
        }
    )+}
}

pub(crate) use payloaded;

payloaded!(
    WhoAmIResponse: WhoAmIResult, 
    ListEndpointsResponse: ListEndpointsResult,
    CreateSessionResponse: CreateSessionResult,
    ExecuteDataQueryResponse: ExecuteQueryResult,
    BeginTransactionResponse: BeginTransactionResult,
    CommitTransactionResponse: CommitTransactionResult,
    PrepareDataQueryResponse: PrepareQueryResult,
    ExplainDataQueryResponse: ExplainQueryResult,

    BulkUpsertResponse: BulkUpsertResult,
    DescribeTableOptionsResponse: DescribeTableOptionsResult,
    DescribeTableResponse: DescribeTableResult,
    KeepAliveResponse: KeepAliveResult,
);