cassandra_proto/frame/
frame_response.rs

1use std::io::Cursor;
2
3use crate::frame::FromCursor;
4use crate::error;
5use crate::frame::Opcode;
6use crate::frame::frame_result::{BodyResResultPrepared, BodyResResultRows, BodyResResultSetKeyspace,
7                          BodyResResultVoid, ResResultBody, RowsMetadata};
8use crate::frame::frame_event::BodyResEvent;
9use crate::frame::frame_error::CDRSError;
10use crate::frame::frame_supported::*;
11use crate::frame::frame_auth_challenge::*;
12use crate::frame::frame_authenticate::BodyResAuthenticate;
13use crate::frame::frame_auth_success::BodyReqAuthSuccess;
14use crate::types::rows::Row;
15
16#[derive(Debug)]
17pub enum ResponseBody {
18    Error(CDRSError),
19    Startup,
20    Ready(BodyResResultVoid),
21    Authenticate(BodyResAuthenticate),
22    Options,
23    Supported(BodyResSupported),
24    Query,
25    Result(ResResultBody),
26    Prepare,
27    Execute,
28    Register,
29    Event(BodyResEvent),
30    Batch,
31    AuthChallenge(BodyResAuthChallenge),
32    AuthResponse,
33    AuthSuccess(BodyReqAuthSuccess),
34}
35
36impl ResponseBody {
37    pub fn from(bytes: &[u8], response_type: &Opcode) -> error::Result<ResponseBody> {
38        let mut cursor: Cursor<&[u8]> = Cursor::new(bytes);
39        Ok(match *response_type {
40            // request frames
41            Opcode::Startup => unreachable!(),
42            Opcode::Options => unreachable!(),
43            Opcode::Query => unreachable!(),
44            Opcode::Prepare => unreachable!(),
45            Opcode::Execute => unreachable!(),
46            Opcode::Register => unreachable!(),
47            Opcode::Batch => unreachable!(),
48            Opcode::AuthResponse => unreachable!(),
49
50            // response frames
51            Opcode::Error => ResponseBody::Error(CDRSError::from_cursor(&mut cursor)?),
52            Opcode::Ready => ResponseBody::Ready(BodyResResultVoid::from_cursor(&mut cursor)?),
53            Opcode::Authenticate => {
54                ResponseBody::Authenticate(BodyResAuthenticate::from_cursor(&mut cursor)?)
55            }
56            Opcode::Supported => {
57                ResponseBody::Supported(BodyResSupported::from_cursor(&mut cursor)?)
58            }
59            Opcode::Result => ResponseBody::Result(ResResultBody::from_cursor(&mut cursor)?),
60            Opcode::Event => ResponseBody::Event(BodyResEvent::from_cursor(&mut cursor)?),
61            Opcode::AuthChallenge => {
62                ResponseBody::AuthChallenge(BodyResAuthChallenge::from_cursor(&mut cursor)?)
63            }
64            Opcode::AuthSuccess => {
65                ResponseBody::AuthSuccess(BodyReqAuthSuccess::from_cursor(&mut cursor)?)
66            }
67        })
68    }
69
70    pub fn into_rows(self) -> Option<Vec<Row>> {
71        match self {
72            ResponseBody::Result(res) => res.into_rows(),
73            _ => None,
74        }
75    }
76
77    pub fn as_rows_metadata(&self) -> Option<RowsMetadata> {
78        match *self {
79            ResponseBody::Result(ref res) => res.as_rows_metadata(),
80            _ => None,
81        }
82    }
83
84    pub fn as_cols(&self) -> Option<&BodyResResultRows> {
85        match *self {
86            ResponseBody::Result(ref res) => match res {
87                &ResResultBody::Rows(ref rows) => Some(rows),
88                _ => None,
89            },
90            _ => None,
91        }
92    }
93
94    /// It unwraps body and returns BodyResResultPrepared which contains an exact result of
95    /// PREPARE query. If frame body is not of type `Result` this method returns `None`.
96    pub fn into_prepared(self) -> Option<BodyResResultPrepared> {
97        match self {
98            ResponseBody::Result(res) => res.into_prepared(),
99            _ => None,
100        }
101    }
102
103    /// It unwraps body and returns BodyResResultPrepared which contains an exact result of
104    /// use keyspace query. If frame body is not of type `Result` this method returns `None`.
105    pub fn into_set_keyspace(self) -> Option<BodyResResultSetKeyspace> {
106        match self {
107            ResponseBody::Result(res) => res.into_set_keyspace(),
108            _ => None,
109        }
110    }
111
112    /// It unwraps body and returns BodyResEvent.
113    /// If frame body is not of type `Result` this method returns `None`.
114    pub fn into_server_event(self) -> Option<BodyResEvent> {
115        match self {
116            ResponseBody::Event(event) => Some(event),
117            _ => None,
118        }
119    }
120
121    pub fn get_authenticator<'a>(&'a self) -> Option<&'a str> {
122        match *self {
123            ResponseBody::Authenticate(ref auth) => Some(auth.data.as_str()),
124            _ => None,
125        }
126    }
127}