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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
use bytebuffer::ByteBuffer;

use crate::encode::VoltError;

#[derive(Debug, Clone, PartialEq)]
pub enum ResponseStatus {
    Success,
    UserAbort,
    GracefulFailure,
    UnexpectedFailure,
    ConnectionLost,
    ServerUnavailable,
    ConnectionTimeout,
    ResponseUnknown,
    TXNRestart,
    OperationalFailure,

    // -10 to -12 are not in the client's preview
    UnsupportedDynamicChange,
    UninitializedAppStatusCode,
    Customized(i8),
}

impl From<i8> for ResponseStatus {
    fn from(s: i8) -> Self {
        match s {
            1 => ResponseStatus::Success,
            -1 => ResponseStatus::UserAbort,
            -2 => ResponseStatus::GracefulFailure,
            -3 => ResponseStatus::UnexpectedFailure,
            -4 => ResponseStatus::ConnectionLost,
            -5 => ResponseStatus::ServerUnavailable,
            -6 => ResponseStatus::ConnectionTimeout,
            -7 => ResponseStatus::ResponseUnknown,
            -8 => ResponseStatus::TXNRestart,
            -9 => ResponseStatus::OperationalFailure,
            -13 => ResponseStatus::UnsupportedDynamicChange,
            -128 => ResponseStatus::UninitializedAppStatusCode,
            _ => {
                ResponseStatus::Customized(s)
            }
        }
    }
}

#[derive(Debug, Clone)]
pub struct VoltResponseInfo {
    handle: i64,
    status: ResponseStatus,
    status_string: String,
    app_status: ResponseStatus,
    app_status_string: String,
    cluster_round_trip_time: i32,
    num_tables: i16,
}

impl VoltResponseInfo {
    #[allow(dead_code)]
    pub fn get_rows_number(&self) -> i16 {
        return self.num_tables;
    }
    pub fn get_status(&self) -> ResponseStatus {
        return self.status.clone();
    }
}

impl VoltResponseInfo {
    pub fn new(bytebuffer: &mut ByteBuffer, handle: i64) -> Result<Self, VoltError> {
        let fields_present = bytebuffer.read_u8()?;
        let status = ResponseStatus::from(bytebuffer.read_i8()?);
        let mut status_string = "".to_owned();
        if fields_present & (1 << 5) != 0 {
            status_string = bytebuffer.read_string()?;
        }
        let app_status = ResponseStatus::from(bytebuffer.read_i8()?);
        let mut app_status_string = "".to_owned();
        if fields_present & (1 << 7) != 0 {
            app_status_string = bytebuffer.read_string()?;
        }
        let cluster_round_trip_time = bytebuffer.read_i32()?;
        let num_tables = bytebuffer.read_i16()?;
        if num_tables < 0 {
            return Err(VoltError::NegativeNumTables(num_tables));
        }
        Ok(VoltResponseInfo {
            handle,
            status,
            status_string,
            app_status,
            app_status_string,
            cluster_round_trip_time,
            num_tables,
        })
    }
}