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
 96
 97
 98
 99
100
101
102
103
use bytebuffer::ByteBuffer;

use crate::encode::VoltError;
use crate::response::ResponseStatus::Success;

#[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 Default for ResponseStatus {
    fn default() -> Self {
        return Success;
    }
}

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, Default)]
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,
        })
    }
}