cassandra_protocol/frame/
message_execute.rs

1use crate::error;
2use crate::frame::{Direction, Envelope, Flags, FromCursor, Opcode, Serialize, Version};
3use crate::query::QueryParams;
4use crate::types::CBytesShort;
5use derive_more::Constructor;
6use std::io::Cursor;
7
8/// The structure that represents a body of a envelope of type `execute`.
9#[derive(Debug, Constructor, Eq, PartialEq, Clone)]
10pub struct BodyReqExecute<'a> {
11    pub id: &'a CBytesShort,
12    pub result_metadata_id: Option<&'a CBytesShort>,
13    pub query_parameters: &'a QueryParams,
14}
15
16impl<'a> Serialize for BodyReqExecute<'a> {
17    fn serialize(&self, cursor: &mut Cursor<&mut Vec<u8>>, version: Version) {
18        self.id.serialize(cursor, version);
19
20        if let Some(result_metadata_id) = self.result_metadata_id {
21            result_metadata_id.serialize(cursor, version);
22        }
23
24        self.query_parameters.serialize(cursor, version);
25    }
26
27    #[inline]
28    fn serialize_to_vec(&self, version: Version) -> Vec<u8> {
29        let mut buf = Vec::with_capacity(
30            self.id.serialized_len()
31                + self
32                    .result_metadata_id
33                    .map(|id| id.serialized_len())
34                    .unwrap_or(0),
35        );
36
37        self.serialize(&mut Cursor::new(&mut buf), version);
38        buf
39    }
40}
41
42/// The structure that represents an owned body of a envelope of type `execute`.
43#[derive(Debug, Constructor, Clone, Eq, PartialEq, Default)]
44pub struct BodyReqExecuteOwned {
45    pub id: CBytesShort,
46    pub result_metadata_id: Option<CBytesShort>,
47    pub query_parameters: QueryParams,
48}
49
50impl FromCursor for BodyReqExecuteOwned {
51    fn from_cursor(cursor: &mut Cursor<&[u8]>, version: Version) -> error::Result<Self> {
52        let id = CBytesShort::from_cursor(cursor, version)?;
53
54        let result_metadata_id = if version >= Version::V5 {
55            Some(CBytesShort::from_cursor(cursor, version)?)
56        } else {
57            None
58        };
59
60        let query_parameters = QueryParams::from_cursor(cursor, version)?;
61
62        Ok(BodyReqExecuteOwned::new(
63            id,
64            result_metadata_id,
65            query_parameters,
66        ))
67    }
68}
69
70impl Serialize for BodyReqExecuteOwned {
71    fn serialize(&self, cursor: &mut Cursor<&mut Vec<u8>>, version: Version) {
72        BodyReqExecute::new(
73            &self.id,
74            self.result_metadata_id.as_ref(),
75            &self.query_parameters,
76        )
77        .serialize(cursor, version);
78    }
79}
80
81impl Envelope {
82    pub fn new_req_execute(
83        id: &CBytesShort,
84        result_metadata_id: Option<&CBytesShort>, // only required for protocol >= V5
85        query_parameters: &QueryParams,
86        flags: Flags,
87        version: Version,
88    ) -> Envelope {
89        let direction = Direction::Request;
90        let opcode = Opcode::Execute;
91
92        let body = BodyReqExecute::new(id, result_metadata_id, query_parameters);
93
94        Envelope::new(
95            version,
96            direction,
97            flags,
98            opcode,
99            0,
100            body.serialize_to_vec(version),
101            None,
102            vec![],
103        )
104    }
105}
106
107#[cfg(test)]
108mod tests {
109    use crate::consistency::Consistency;
110    use crate::frame::message_execute::BodyReqExecuteOwned;
111    use crate::frame::traits::Serialize;
112    use crate::frame::{FromCursor, Version};
113    use crate::query::QueryParams;
114    use crate::types::CBytesShort;
115    use std::io::Cursor;
116
117    #[test]
118    fn should_deserialize_body() {
119        let data = [0, 1, 2, 0, 0, 0];
120        let mut cursor = Cursor::new(data.as_slice());
121
122        let body = BodyReqExecuteOwned::from_cursor(&mut cursor, Version::V4).unwrap();
123        assert_eq!(body.id, CBytesShort::new(vec![2]));
124        assert_eq!(body.query_parameters.consistency, Consistency::Any);
125    }
126
127    #[test]
128    fn should_support_result_metadata_id() {
129        let body = BodyReqExecuteOwned::new(
130            CBytesShort::new(vec![1]),
131            Some(CBytesShort::new(vec![2])),
132            QueryParams::default(),
133        );
134        let data = body.serialize_to_vec(Version::V5);
135        assert_eq!(
136            BodyReqExecuteOwned::from_cursor(&mut Cursor::new(&data), Version::V5).unwrap(),
137            body
138        );
139    }
140}