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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use crate::consistency::Consistency;
use crate::frame::AsByte;
use crate::frame::IntoBytes;
use crate::query::query_flags::QueryFlags;
use crate::query::query_values::QueryValues;
use crate::types::{to_bigint, to_int, to_short, CBytes};

/// Parameters of Query for query operation.
#[derive(Debug, Default)]
pub struct QueryParams {
    /// Cassandra consistency level.
    pub consistency: Consistency,
    /// Array of query flags.
    pub flags: Vec<QueryFlags>,
    /// Were values provided with names
    pub with_names: Option<bool>,
    /// Array of values.
    pub values: Option<QueryValues>,
    /// Page size.
    pub page_size: Option<i32>,
    /// Array of bytes which represents paging state.
    pub paging_state: Option<CBytes>,
    /// Serial `Consistency`.
    pub serial_consistency: Option<Consistency>,
    /// Timestamp.
    pub timestamp: Option<i64>,
}

impl QueryParams {
    /// Sets values of Query request params.
    pub fn set_values(&mut self, values: QueryValues) {
        self.flags.push(QueryFlags::Value);
        self.values = Some(values);
    }

    fn flags_as_byte(&self) -> u8 {
        self.flags.iter().fold(0, |acc, flag| acc | flag.as_byte())
    }

    #[allow(dead_code)]
    fn parse_query_flags(byte: u8) -> Vec<QueryFlags> {
        let mut flags: Vec<QueryFlags> = vec![];

        if QueryFlags::has_value(byte) {
            flags.push(QueryFlags::Value);
        }
        if QueryFlags::has_skip_metadata(byte) {
            flags.push(QueryFlags::SkipMetadata);
        }
        if QueryFlags::has_page_size(byte) {
            flags.push(QueryFlags::PageSize);
        }
        if QueryFlags::has_with_paging_state(byte) {
            flags.push(QueryFlags::WithPagingState);
        }
        if QueryFlags::has_with_serial_consistency(byte) {
            flags.push(QueryFlags::WithSerialConsistency);
        }
        if QueryFlags::has_with_default_timestamp(byte) {
            flags.push(QueryFlags::WithDefaultTimestamp);
        }
        if QueryFlags::has_with_names_for_values(byte) {
            flags.push(QueryFlags::WithNamesForValues);
        }

        flags
    }
}

impl IntoBytes for QueryParams {
    fn into_cbytes(&self) -> Vec<u8> {
        let mut v: Vec<u8> = vec![];

        v.extend_from_slice(self.consistency.into_cbytes().as_slice());
        v.push(self.flags_as_byte());
        if QueryFlags::has_value(self.flags_as_byte()) {
            if let Some(ref values) = self.values {
                v.extend_from_slice(to_short(values.len() as i16).as_slice());
                v.extend_from_slice(values.into_cbytes().as_slice());
            }
        }
        if QueryFlags::has_page_size(self.flags_as_byte()) && self.page_size.is_some() {
            // XXX clone
            v.extend_from_slice(
                to_int(
                    self.page_size
                        .clone()
                        // unwrap is safe as we've checked that
                        // self.page_size.is_some()
                        .unwrap(),
                )
                .as_slice(),
            );
        }
        if QueryFlags::has_with_paging_state(self.flags_as_byte()) && self.paging_state.is_some() {
            // XXX clone
            v.extend_from_slice(
                self.paging_state
                    .clone()
                    // unwrap is safe as we've checked that
                    // self.paging_state.is_some()
                    .unwrap()
                    .into_cbytes()
                    .as_slice(),
            );
        }
        if QueryFlags::has_with_serial_consistency(self.flags_as_byte())
            && self.serial_consistency.is_some()
        {
            // XXX clone
            v.extend_from_slice(
                self.serial_consistency
                    .clone()
                    // unwrap is safe as we've checked that
                    // self.serial_consistency.is_some()
                    .unwrap()
                    .into_cbytes()
                    .as_slice(),
            );
        }
        if QueryFlags::has_with_default_timestamp(self.flags_as_byte()) && self.timestamp.is_some()
        {
            // unwrap is safe as we've checked that self.timestamp.is_some()
            v.extend_from_slice(to_bigint(self.timestamp.unwrap()).as_slice());
        }

        v
    }
}