Skip to main content

scylla_cql/frame/response/
mod.rs

1//! CQL responses sent by the server.
2
3pub mod authenticate;
4pub mod custom_type_parser;
5pub use scylla_cql_core::frame::response::error;
6pub mod event;
7pub mod result;
8pub mod supported;
9
10use std::sync::Arc;
11
12pub use error::Error;
13pub use scylla_cql_core::frame::response::CqlResponseKind;
14pub use supported::Supported;
15
16use crate::frame::TryFromPrimitiveError;
17use crate::frame::frame_errors::ResultMetadataAndRowsCountParseError;
18use crate::frame::protocol_features::ProtocolFeatures;
19use crate::frame::response::result::ResultMetadata;
20
21use super::frame_errors::CqlResponseParseError;
22
23/// Opcode of a response, used to identify the response type in a CQL frame.
24#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
25#[repr(u8)]
26pub enum ResponseOpcode {
27    /// See [CqlResponseKind::Error].
28    Error = 0x00,
29    /// See [CqlResponseKind::Ready].
30    Ready = 0x02,
31    /// See [CqlResponseKind::Authenticate].
32    Authenticate = 0x03,
33    /// See [CqlResponseKind::Supported].
34    Supported = 0x06,
35    /// See [CqlResponseKind::Result].
36    Result = 0x08,
37    /// See [CqlResponseKind::Event].
38    Event = 0x0C,
39    /// See [CqlResponseKind::AuthChallenge].
40    AuthChallenge = 0x0E,
41    /// See [CqlResponseKind::AuthSuccess].
42    AuthSuccess = 0x10,
43}
44
45impl TryFrom<u8> for ResponseOpcode {
46    type Error = TryFromPrimitiveError<u8>;
47
48    fn try_from(value: u8) -> Result<Self, TryFromPrimitiveError<u8>> {
49        match value {
50            0x00 => Ok(Self::Error),
51            0x02 => Ok(Self::Ready),
52            0x03 => Ok(Self::Authenticate),
53            0x06 => Ok(Self::Supported),
54            0x08 => Ok(Self::Result),
55            0x0C => Ok(Self::Event),
56            0x0E => Ok(Self::AuthChallenge),
57            0x10 => Ok(Self::AuthSuccess),
58            _ => Err(TryFromPrimitiveError::new("ResponseOpcode", value)),
59        }
60    }
61}
62
63/// A CQL response that has been received from the server.
64#[derive(Debug)]
65pub enum Response {
66    /// ERROR response, returned by the server when an error occurs.
67    Error(Error),
68    /// READY response, indicating that the server is ready to process requests,
69    /// typically after a connection is established.
70    Ready,
71    /// RESULT response, containing the result of a statement execution.
72    Result(result::Result),
73    /// AUTHENTICATE response, indicating that the server requires authentication.
74    Authenticate(authenticate::Authenticate),
75    /// AUTH_SUCCESS response, indicating that the authentication was successful.
76    AuthSuccess(authenticate::AuthSuccess),
77    /// AUTH_CHALLENGE response, indicating that the server requires further authentication.
78    AuthChallenge(authenticate::AuthChallenge),
79    /// SUPPORTED response, containing the features supported by the server.
80    Supported(Supported),
81    /// EVENT response, containing an event that occurred on the server.
82    Event(event::Event),
83}
84
85/// A CQL response that has been received from the server.
86#[derive(Debug)]
87#[non_exhaustive]
88pub enum ResponseV2 {
89    /// ERROR response, returned by the server when an error occurs.
90    Error(Error),
91    /// READY response, indicating that the server is ready to process requests,
92    /// typically after a connection is established.
93    Ready,
94    /// RESULT response, containing the result of a statement execution.
95    Result(result::Result),
96    /// AUTHENTICATE response, indicating that the server requires authentication.
97    Authenticate(authenticate::Authenticate),
98    /// AUTH_SUCCESS response, indicating that the authentication was successful.
99    AuthSuccess(authenticate::AuthSuccess),
100    /// AUTH_CHALLENGE response, indicating that the server requires further authentication.
101    AuthChallenge(authenticate::AuthChallenge),
102    /// SUPPORTED response, containing the features supported by the server.
103    Supported(Supported),
104    /// EVENT response, containing an event that occurred on the server.
105    Event(event::EventV2),
106}
107
108impl Response {
109    /// Returns the kind of this response.
110    pub fn to_response_kind(&self) -> CqlResponseKind {
111        match self {
112            Response::Error(_) => CqlResponseKind::Error,
113            Response::Ready => CqlResponseKind::Ready,
114            Response::Result(_) => CqlResponseKind::Result,
115            Response::Authenticate(_) => CqlResponseKind::Authenticate,
116            Response::AuthSuccess(_) => CqlResponseKind::AuthSuccess,
117            Response::AuthChallenge(_) => CqlResponseKind::AuthChallenge,
118            Response::Supported(_) => CqlResponseKind::Supported,
119            Response::Event(_) => CqlResponseKind::Event,
120        }
121    }
122
123    /// Deserialize a response from the given bytes.
124    pub fn deserialize(
125        features: &ProtocolFeatures,
126        opcode: ResponseOpcode,
127        buf_bytes: bytes::Bytes,
128        cached_metadata: Option<&Arc<ResultMetadata<'static>>>,
129    ) -> Result<Response, CqlResponseParseError> {
130        let buf = &mut &*buf_bytes;
131        let response = match opcode {
132            ResponseOpcode::Error => Response::Error(Error::deserialize(features, buf)?),
133            ResponseOpcode::Ready => Response::Ready,
134            ResponseOpcode::Authenticate => {
135                Response::Authenticate(authenticate::Authenticate::deserialize(buf)?)
136            }
137            ResponseOpcode::Supported => Response::Supported(Supported::deserialize(buf)?),
138            ResponseOpcode::Result => Response::Result(result::deserialize_with_features(
139                buf_bytes,
140                cached_metadata,
141                features,
142            )?),
143            ResponseOpcode::Event => Response::Event(event::Event::deserialize(buf)?),
144            ResponseOpcode::AuthChallenge => {
145                Response::AuthChallenge(authenticate::AuthChallenge::deserialize(buf)?)
146            }
147            ResponseOpcode::AuthSuccess => {
148                Response::AuthSuccess(authenticate::AuthSuccess::deserialize(buf)?)
149            }
150        };
151
152        Ok(response)
153    }
154
155    pub fn deserialize_metadata(
156        self,
157    ) -> Result<ResponseWithDeserializedMetadata, ResultMetadataAndRowsCountParseError> {
158        let result = match self {
159            Self::Error(e) => ResponseWithDeserializedMetadata::Error(e),
160            Self::Ready => ResponseWithDeserializedMetadata::Ready,
161            Self::Result(res) => {
162                ResponseWithDeserializedMetadata::Result(res.deserialize_metadata()?)
163            }
164            Self::Authenticate(auth) => ResponseWithDeserializedMetadata::Authenticate(auth),
165            Self::AuthSuccess(auth_succ) => {
166                ResponseWithDeserializedMetadata::AuthSuccess(auth_succ)
167            }
168            Self::AuthChallenge(auth_chal) => {
169                ResponseWithDeserializedMetadata::AuthChallenge(auth_chal)
170            }
171            Self::Supported(sup) => ResponseWithDeserializedMetadata::Supported(sup),
172            Self::Event(eve) => ResponseWithDeserializedMetadata::Event(eve),
173        };
174        Ok(result)
175    }
176
177    /// Converts this response into a `NonErrorResponse`, returning an error if it is an `Error` response.
178    pub fn into_non_error_response(self) -> Result<NonErrorResponse, error::Error> {
179        let non_error_response = match self {
180            Response::Error(e) => return Err(e),
181            Response::Ready => NonErrorResponse::Ready,
182            Response::Result(res) => NonErrorResponse::Result(res),
183            Response::Authenticate(auth) => NonErrorResponse::Authenticate(auth),
184            Response::AuthSuccess(auth_succ) => NonErrorResponse::AuthSuccess(auth_succ),
185            Response::AuthChallenge(auth_chal) => NonErrorResponse::AuthChallenge(auth_chal),
186            Response::Supported(sup) => NonErrorResponse::Supported(sup),
187            Response::Event(eve) => NonErrorResponse::Event(eve),
188        };
189
190        Ok(non_error_response)
191    }
192}
193
194impl ResponseV2 {
195    /// Returns the kind of this response.
196    pub fn to_response_kind(&self) -> CqlResponseKind {
197        match self {
198            Self::Error(_) => CqlResponseKind::Error,
199            Self::Ready => CqlResponseKind::Ready,
200            Self::Result(_) => CqlResponseKind::Result,
201            Self::Authenticate(_) => CqlResponseKind::Authenticate,
202            Self::AuthSuccess(_) => CqlResponseKind::AuthSuccess,
203            Self::AuthChallenge(_) => CqlResponseKind::AuthChallenge,
204            Self::Supported(_) => CqlResponseKind::Supported,
205            Self::Event(_) => CqlResponseKind::Event,
206        }
207    }
208
209    /// Deserialize a response from the given bytes.
210    pub fn deserialize(
211        features: &ProtocolFeatures,
212        opcode: ResponseOpcode,
213        buf_bytes: bytes::Bytes,
214        cached_metadata: Option<&Arc<ResultMetadata<'static>>>,
215    ) -> Result<Self, CqlResponseParseError> {
216        let buf = &mut &*buf_bytes;
217        let response = match opcode {
218            ResponseOpcode::Error => Self::Error(Error::deserialize(features, buf)?),
219            ResponseOpcode::Ready => Self::Ready,
220            ResponseOpcode::Authenticate => {
221                Self::Authenticate(authenticate::Authenticate::deserialize(buf)?)
222            }
223            ResponseOpcode::Supported => Self::Supported(Supported::deserialize(buf)?),
224            ResponseOpcode::Result => Self::Result(result::deserialize_with_features(
225                buf_bytes,
226                cached_metadata,
227                features,
228            )?),
229            ResponseOpcode::Event => Self::Event(event::EventV2::deserialize(buf)?),
230            ResponseOpcode::AuthChallenge => {
231                Self::AuthChallenge(authenticate::AuthChallenge::deserialize(buf)?)
232            }
233            ResponseOpcode::AuthSuccess => {
234                Self::AuthSuccess(authenticate::AuthSuccess::deserialize(buf)?)
235            }
236        };
237
238        Ok(response)
239    }
240
241    pub fn deserialize_metadata(
242        self,
243    ) -> Result<ResponseWithDeserializedMetadataV2, ResultMetadataAndRowsCountParseError> {
244        let result = match self {
245            Self::Error(e) => ResponseWithDeserializedMetadataV2::Error(e),
246            Self::Ready => ResponseWithDeserializedMetadataV2::Ready,
247            Self::Result(res) => {
248                ResponseWithDeserializedMetadataV2::Result(res.deserialize_metadata()?)
249            }
250            Self::Authenticate(auth) => ResponseWithDeserializedMetadataV2::Authenticate(auth),
251            Self::AuthSuccess(auth_succ) => {
252                ResponseWithDeserializedMetadataV2::AuthSuccess(auth_succ)
253            }
254            Self::AuthChallenge(auth_chal) => {
255                ResponseWithDeserializedMetadataV2::AuthChallenge(auth_chal)
256            }
257            Self::Supported(sup) => ResponseWithDeserializedMetadataV2::Supported(sup),
258            Self::Event(eve) => ResponseWithDeserializedMetadataV2::Event(eve),
259        };
260        Ok(result)
261    }
262}
263
264/// A CQL response that has been received from the server.
265#[derive(Debug)]
266pub enum ResponseWithDeserializedMetadata {
267    /// ERROR response, returned by the server when an error occurs.
268    Error(Error),
269    /// READY response, indicating that the server is ready to process requests,
270    /// typically after a connection is established.
271    Ready,
272    /// RESULT response, containing the result of a statement execution.
273    Result(result::ResultWithDeserializedMetadata),
274    /// AUTHENTICATE response, indicating that the server requires authentication.
275    Authenticate(authenticate::Authenticate),
276    /// AUTH_SUCCESS response, indicating that the authentication was successful.
277    AuthSuccess(authenticate::AuthSuccess),
278    /// AUTH_CHALLENGE response, indicating that the server requires further authentication.
279    AuthChallenge(authenticate::AuthChallenge),
280    /// SUPPORTED response, containing the features supported by the server.
281    Supported(Supported),
282    /// EVENT response, containing an event that occurred on the server.
283    Event(event::Event),
284}
285
286impl ResponseWithDeserializedMetadata {
287    /// Returns the kind of this response.
288    pub fn to_response_kind(&self) -> CqlResponseKind {
289        match self {
290            Self::Error(_) => CqlResponseKind::Error,
291            Self::Ready => CqlResponseKind::Ready,
292            Self::Result(_) => CqlResponseKind::Result,
293            Self::Authenticate(_) => CqlResponseKind::Authenticate,
294            Self::AuthSuccess(_) => CqlResponseKind::AuthSuccess,
295            Self::AuthChallenge(_) => CqlResponseKind::AuthChallenge,
296            Self::Supported(_) => CqlResponseKind::Supported,
297            Self::Event(_) => CqlResponseKind::Event,
298        }
299    }
300
301    /// Converts this response into a `NonErrorResponse`, returning an error if it is an `Error` response.
302    pub fn into_non_error_response(
303        self,
304    ) -> Result<NonErrorResponseWithDeserializedMetadata, error::Error> {
305        let non_error_response = match self {
306            Self::Error(e) => return Err(e),
307            Self::Ready => NonErrorResponseWithDeserializedMetadata::Ready,
308            Self::Result(res) => NonErrorResponseWithDeserializedMetadata::Result(res),
309            Self::Authenticate(auth) => {
310                NonErrorResponseWithDeserializedMetadata::Authenticate(auth)
311            }
312            Self::AuthSuccess(auth_succ) => {
313                NonErrorResponseWithDeserializedMetadata::AuthSuccess(auth_succ)
314            }
315            Self::AuthChallenge(auth_chal) => {
316                NonErrorResponseWithDeserializedMetadata::AuthChallenge(auth_chal)
317            }
318            Self::Supported(sup) => NonErrorResponseWithDeserializedMetadata::Supported(sup),
319            Self::Event(eve) => NonErrorResponseWithDeserializedMetadata::Event(eve),
320        };
321
322        Ok(non_error_response)
323    }
324}
325
326/// A CQL response that has been received from the server.
327#[derive(Debug)]
328#[non_exhaustive]
329pub enum ResponseWithDeserializedMetadataV2 {
330    /// ERROR response, returned by the server when an error occurs.
331    Error(Error),
332    /// READY response, indicating that the server is ready to process requests,
333    /// typically after a connection is established.
334    Ready,
335    /// RESULT response, containing the result of a statement execution.
336    Result(result::ResultWithDeserializedMetadata),
337    /// AUTHENTICATE response, indicating that the server requires authentication.
338    Authenticate(authenticate::Authenticate),
339    /// AUTH_SUCCESS response, indicating that the authentication was successful.
340    AuthSuccess(authenticate::AuthSuccess),
341    /// AUTH_CHALLENGE response, indicating that the server requires further authentication.
342    AuthChallenge(authenticate::AuthChallenge),
343    /// SUPPORTED response, containing the features supported by the server.
344    Supported(Supported),
345    /// EVENT response, containing an event that occurred on the server.
346    Event(event::EventV2),
347}
348
349impl ResponseWithDeserializedMetadataV2 {
350    /// Returns the kind of this response.
351    pub fn to_response_kind(&self) -> CqlResponseKind {
352        match self {
353            Self::Error(_) => CqlResponseKind::Error,
354            Self::Ready => CqlResponseKind::Ready,
355            Self::Result(_) => CqlResponseKind::Result,
356            Self::Authenticate(_) => CqlResponseKind::Authenticate,
357            Self::AuthSuccess(_) => CqlResponseKind::AuthSuccess,
358            Self::AuthChallenge(_) => CqlResponseKind::AuthChallenge,
359            Self::Supported(_) => CqlResponseKind::Supported,
360            Self::Event(_) => CqlResponseKind::Event,
361        }
362    }
363
364    /// Converts this response into a `NonErrorResponseV2`, returning an error if it is an `Error` response.
365    pub fn into_non_error_response(
366        self,
367    ) -> Result<NonErrorResponseWithDeserializedMetadataV2, error::Error> {
368        let non_error_response = match self {
369            Self::Error(e) => return Err(e),
370            Self::Ready => NonErrorResponseWithDeserializedMetadataV2::Ready,
371            Self::Result(res) => NonErrorResponseWithDeserializedMetadataV2::Result(res),
372            Self::Authenticate(auth) => {
373                NonErrorResponseWithDeserializedMetadataV2::Authenticate(auth)
374            }
375            Self::AuthSuccess(auth_succ) => {
376                NonErrorResponseWithDeserializedMetadataV2::AuthSuccess(auth_succ)
377            }
378            Self::AuthChallenge(auth_chal) => {
379                NonErrorResponseWithDeserializedMetadataV2::AuthChallenge(auth_chal)
380            }
381            Self::Supported(sup) => NonErrorResponseWithDeserializedMetadataV2::Supported(sup),
382            Self::Event(eve) => NonErrorResponseWithDeserializedMetadataV2::Event(eve),
383        };
384
385        Ok(non_error_response)
386    }
387}
388
389/// A CQL response that has been received from the server, excluding error responses.
390/// This is used to handle responses that are not errors, allowing for easier processing
391/// of valid responses without need to handle error case any later.
392#[derive(Debug)]
393pub enum NonErrorResponse {
394    /// See [`Response::Ready`].
395    Ready,
396    /// See [`Response::Result`].
397    Result(result::Result),
398    /// See [`Response::Authenticate`].
399    Authenticate(authenticate::Authenticate),
400    /// See [`Response::AuthSuccess`].
401    AuthSuccess(authenticate::AuthSuccess),
402    /// See [`Response::AuthChallenge`].
403    AuthChallenge(authenticate::AuthChallenge),
404    /// See [`Response::Supported`].
405    Supported(Supported),
406    /// See [`Response::Event`].
407    Event(event::Event),
408}
409
410impl NonErrorResponse {
411    /// Returns the kind of this non-error response.
412    pub fn to_response_kind(&self) -> CqlResponseKind {
413        match self {
414            NonErrorResponse::Ready => CqlResponseKind::Ready,
415            NonErrorResponse::Result(_) => CqlResponseKind::Result,
416            NonErrorResponse::Authenticate(_) => CqlResponseKind::Authenticate,
417            NonErrorResponse::AuthSuccess(_) => CqlResponseKind::AuthSuccess,
418            NonErrorResponse::AuthChallenge(_) => CqlResponseKind::AuthChallenge,
419            NonErrorResponse::Supported(_) => CqlResponseKind::Supported,
420            NonErrorResponse::Event(_) => CqlResponseKind::Event,
421        }
422    }
423}
424
425/// A CQL response that has been received from the server, excluding error responses.
426/// This is used to handle responses that are not errors, allowing for easier processing
427/// of valid responses without need to handle error case any later.
428/// The difference from [NonErrorResponse] is that Result::Rows variant holds [result::DeserializedMetadataAndRawRows]
429/// instead of [result::RawMetadataAndRawRows].
430#[derive(Debug)]
431pub enum NonErrorResponseWithDeserializedMetadata {
432    /// See [`Response::Ready`].
433    Ready,
434    /// See [`Response::Result`].
435    Result(result::ResultWithDeserializedMetadata),
436    /// See [`Response::Authenticate`].
437    Authenticate(authenticate::Authenticate),
438    /// See [`Response::AuthSuccess`].
439    AuthSuccess(authenticate::AuthSuccess),
440    /// See [`Response::AuthChallenge`].
441    AuthChallenge(authenticate::AuthChallenge),
442    /// See [`Response::Supported`].
443    Supported(Supported),
444    /// See [`Response::Event`].
445    Event(event::Event),
446}
447
448impl NonErrorResponseWithDeserializedMetadata {
449    /// Returns the kind of this non-error response.
450    pub fn to_response_kind(&self) -> CqlResponseKind {
451        match self {
452            Self::Ready => CqlResponseKind::Ready,
453            Self::Result(_) => CqlResponseKind::Result,
454            Self::Authenticate(_) => CqlResponseKind::Authenticate,
455            Self::AuthSuccess(_) => CqlResponseKind::AuthSuccess,
456            Self::AuthChallenge(_) => CqlResponseKind::AuthChallenge,
457            Self::Supported(_) => CqlResponseKind::Supported,
458            Self::Event(_) => CqlResponseKind::Event,
459        }
460    }
461}
462
463/// A CQL response that has been received from the server, excluding error responses.
464/// This is used to handle responses that are not errors, allowing for easier processing
465/// of valid responses without need to handle error case any later.
466/// The difference from [NonErrorResponse] is that Result::Rows variant holds [result::DeserializedMetadataAndRawRows]
467/// instead of [result::RawMetadataAndRawRows].
468#[derive(Debug)]
469#[non_exhaustive]
470pub enum NonErrorResponseWithDeserializedMetadataV2 {
471    /// See [`Response::Ready`].
472    Ready,
473    /// See [`Response::Result`].
474    Result(result::ResultWithDeserializedMetadata),
475    /// See [`Response::Authenticate`].
476    Authenticate(authenticate::Authenticate),
477    /// See [`Response::AuthSuccess`].
478    AuthSuccess(authenticate::AuthSuccess),
479    /// See [`Response::AuthChallenge`].
480    AuthChallenge(authenticate::AuthChallenge),
481    /// See [`Response::Supported`].
482    Supported(Supported),
483    /// See [`Response::Event`].
484    Event(event::EventV2),
485}
486
487impl NonErrorResponseWithDeserializedMetadataV2 {
488    /// Returns the kind of this non-error response.
489    pub fn to_response_kind(&self) -> CqlResponseKind {
490        match self {
491            Self::Ready => CqlResponseKind::Ready,
492            Self::Result(_) => CqlResponseKind::Result,
493            Self::Authenticate(_) => CqlResponseKind::Authenticate,
494            Self::AuthSuccess(_) => CqlResponseKind::AuthSuccess,
495            Self::AuthChallenge(_) => CqlResponseKind::AuthChallenge,
496            Self::Supported(_) => CqlResponseKind::Supported,
497            Self::Event(_) => CqlResponseKind::Event,
498        }
499    }
500}