1use std::io;
6use std::result;
7
8use crate::error;
9use crate::consistency::Consistency;
10use crate::types::*;
11use crate::frame::traits::FromCursor;
12use crate::frame::Frame;
13
14pub type Result = result::Result<Frame, CDRSError>;
18
19#[derive(Debug)]
24pub struct CDRSError {
25 pub error_code: CInt,
27 pub message: CString,
29 pub additional_info: AdditionalErrorInfo,
31}
32
33impl FromCursor for CDRSError {
34 fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> error::Result<CDRSError> {
35 let error_code = CInt::from_cursor(&mut cursor)?;
36 let message = CString::from_cursor(&mut cursor)?;
37 let additional_info = AdditionalErrorInfo::from_cursor_with_code(&mut cursor, error_code)?;
38
39 Ok(CDRSError { error_code: error_code,
40 message: message,
41 additional_info: additional_info, })
42 }
43}
44
45#[derive(Debug)]
49pub enum AdditionalErrorInfo {
50 Server(SimpleError),
51 Protocol(SimpleError),
52 Authentication(SimpleError),
53 Unavailable(UnavailableError),
54 Overloaded(SimpleError),
55 IsBootstrapping(SimpleError),
56 Truncate(SimpleError),
57 WriteTimeout(WriteTimeoutError),
58 ReadTimeout(ReadTimeoutError),
59 ReadFailure(ReadFailureError),
60 FunctionFailure(FunctionFailureError),
61 WriteFailure(WriteFailureError),
62 Syntax(SimpleError),
63 Unauthorized(SimpleError),
64 Invalid(SimpleError),
65 Config(SimpleError),
66 AlreadyExists(AlreadyExistsError),
67 Unprepared(UnpreparedError),
68}
69
70impl AdditionalErrorInfo {
71 pub fn from_cursor_with_code(mut cursor: &mut io::Cursor<&[u8]>,
72 error_code: CInt)
73 -> error::Result<AdditionalErrorInfo> {
74 match error_code {
75 0x0000 => Ok(AdditionalErrorInfo::Server(SimpleError::from_cursor(
76 &mut cursor,
77 )?)),
78 0x000A => Ok(AdditionalErrorInfo::Protocol(SimpleError::from_cursor(
79 &mut cursor,
80 )?)),
81 0x0100 => Ok(AdditionalErrorInfo::Authentication(
82 SimpleError::from_cursor(&mut cursor)?,
83 )),
84 0x1000 => Ok(AdditionalErrorInfo::Unavailable(
85 UnavailableError::from_cursor(&mut cursor)?,
86 )),
87 0x1001 => Ok(AdditionalErrorInfo::Overloaded(SimpleError::from_cursor(
88 &mut cursor,
89 )?)),
90 0x1002 => Ok(AdditionalErrorInfo::IsBootstrapping(
91 SimpleError::from_cursor(&mut cursor)?,
92 )),
93 0x1003 => Ok(AdditionalErrorInfo::Truncate(SimpleError::from_cursor(
94 &mut cursor,
95 )?)),
96 0x1100 => Ok(AdditionalErrorInfo::WriteTimeout(
97 WriteTimeoutError::from_cursor(&mut cursor)?,
98 )),
99 0x1200 => Ok(AdditionalErrorInfo::ReadTimeout(
100 ReadTimeoutError::from_cursor(&mut cursor)?,
101 )),
102 0x1300 => Ok(AdditionalErrorInfo::ReadFailure(
103 ReadFailureError::from_cursor(&mut cursor)?,
104 )),
105 0x1400 => Ok(AdditionalErrorInfo::FunctionFailure(
106 FunctionFailureError::from_cursor(&mut cursor)?,
107 )),
108 0x1500 => Ok(AdditionalErrorInfo::WriteFailure(
109 WriteFailureError::from_cursor(&mut cursor)?,
110 )),
111 0x2000 => Ok(AdditionalErrorInfo::Syntax(SimpleError::from_cursor(
112 &mut cursor,
113 )?)),
114 0x2100 => Ok(AdditionalErrorInfo::Unauthorized(
115 SimpleError::from_cursor(&mut cursor)?,
116 )),
117 0x2200 => Ok(AdditionalErrorInfo::Invalid(SimpleError::from_cursor(
118 &mut cursor,
119 )?)),
120 0x2300 => Ok(AdditionalErrorInfo::Config(SimpleError::from_cursor(
121 &mut cursor,
122 )?)),
123 0x2400 => Ok(AdditionalErrorInfo::AlreadyExists(
124 AlreadyExistsError::from_cursor(&mut cursor)?,
125 )),
126 0x2500 => Ok(AdditionalErrorInfo::Unprepared(
127 UnpreparedError::from_cursor(&mut cursor)?,
128 )),
129 code => Err(format!("Unexpected error code received: {}", code).into()),
130 }
131 }
132}
133
134#[derive(Debug)]
136pub struct SimpleError {}
137
138impl FromCursor for SimpleError {
139 fn from_cursor(mut _cursor: &mut io::Cursor<&[u8]>) -> error::Result<SimpleError> {
140 Ok(SimpleError {})
141 }
142}
143
144#[derive(Debug)]
148pub struct UnavailableError {
149 pub cl: Consistency,
151 pub required: CInt,
153 pub alive: CInt,
155}
156
157impl FromCursor for UnavailableError {
158 fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> error::Result<UnavailableError> {
159 let cl = Consistency::from_cursor(&mut cursor)?;
160 let required = CInt::from_cursor(&mut cursor)?;
161 let alive = CInt::from_cursor(&mut cursor)?;
162
163 Ok(UnavailableError { cl: cl,
164 required: required,
165 alive: alive, })
166 }
167}
168
169#[derive(Debug)]
171pub struct WriteTimeoutError {
172 pub cl: Consistency,
174 pub received: CInt,
176 pub blockfor: CInt,
178 pub write_type: WriteType,
180}
181
182impl FromCursor for WriteTimeoutError {
183 fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> error::Result<WriteTimeoutError> {
184 let cl = Consistency::from_cursor(&mut cursor)?;
185 let received = CInt::from_cursor(&mut cursor)?;
186 let blockfor = CInt::from_cursor(&mut cursor)?;
187 let write_type = WriteType::from_cursor(&mut cursor)?;
188
189 Ok(WriteTimeoutError { cl: cl,
190 received: received,
191 blockfor: blockfor,
192 write_type: write_type, })
193 }
194}
195
196#[derive(Debug)]
198pub struct ReadTimeoutError {
199 pub cl: Consistency,
201 pub received: CInt,
203 pub blockfor: CInt,
205 data_present: u8,
206}
207
208impl ReadTimeoutError {
209 pub fn replica_has_responded(&self) -> bool {
211 self.data_present != 0
212 }
213}
214
215impl FromCursor for ReadTimeoutError {
216 fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> error::Result<ReadTimeoutError> {
217 let cl = Consistency::from_cursor(&mut cursor)?;
218 let received = CInt::from_cursor(&mut cursor)?;
219 let blockfor = CInt::from_cursor(&mut cursor)?;
220 let data_present = try_from_bytes(cursor_next_value(&mut cursor, 1)?.as_slice())? as u8;
221
222 Ok(ReadTimeoutError { cl: cl,
223 received: received,
224 blockfor: blockfor,
225 data_present: data_present, })
226 }
227}
228
229#[derive(Debug)]
231pub struct ReadFailureError {
232 pub cl: Consistency,
234 pub received: CInt,
236 pub blockfor: CInt,
238 pub num_failures: CInt,
240 data_present: u8,
241}
242
243impl ReadFailureError {
244 pub fn replica_has_responded(&self) -> bool {
246 self.data_present != 0
247 }
248}
249
250impl FromCursor for ReadFailureError {
251 fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> error::Result<ReadFailureError> {
252 let cl = Consistency::from_cursor(&mut cursor)?;
253 let received = CInt::from_cursor(&mut cursor)?;
254 let blockfor = CInt::from_cursor(&mut cursor)?;
255 let num_failures = CInt::from_cursor(&mut cursor)?;
256 let data_present = try_from_bytes(cursor_next_value(&mut cursor, 1)?.as_slice())? as u8;
257
258 Ok(ReadFailureError { cl: cl,
259 received: received,
260 blockfor: blockfor,
261 num_failures: num_failures,
262 data_present: data_present, })
263 }
264}
265
266#[derive(Debug)]
268pub struct FunctionFailureError {
269 pub keyspace: CString,
271 pub function: CString,
273 pub arg_types: CStringList,
275}
276
277impl FromCursor for FunctionFailureError {
278 fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> error::Result<FunctionFailureError> {
279 let keyspace = CString::from_cursor(&mut cursor)?;
280 let function = CString::from_cursor(&mut cursor)?;
281 let arg_types = CStringList::from_cursor(&mut cursor)?;
282
283 Ok(FunctionFailureError { keyspace: keyspace,
284 function: function,
285 arg_types: arg_types, })
286 }
287}
288
289#[derive(Debug)]
292pub struct WriteFailureError {
293 pub cl: Consistency,
295 pub received: CInt,
297 pub blockfor: CInt,
299 pub num_failures: CInt,
301 pub write_type: WriteType,
303}
304
305impl FromCursor for WriteFailureError {
306 fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> error::Result<WriteFailureError> {
307 let cl = Consistency::from_cursor(&mut cursor)?;
308 let received = CInt::from_cursor(&mut cursor)?;
309 let blockfor = CInt::from_cursor(&mut cursor)?;
310 let num_failures = CInt::from_cursor(&mut cursor)?;
311 let write_type = WriteType::from_cursor(&mut cursor)?;
312
313 Ok(WriteFailureError { cl: cl,
314 received: received,
315 blockfor: blockfor,
316 num_failures: num_failures,
317 write_type: write_type, })
318 }
319}
320
321#[derive(Debug)]
324pub enum WriteType {
325 Simple,
327 Batch,
331 UnloggedBatch,
333 Counter,
335 BatchLog,
338}
339
340impl FromCursor for WriteType {
341 fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> error::Result<WriteType> {
342 CString::from_cursor(&mut cursor).and_then(|wt| match wt.as_str() {
343 "SIMPLE" => Ok(WriteType::Simple),
344 "BATCH" => Ok(WriteType::Batch),
345 "UNLOGGED_BATCH" => {
346 Ok(WriteType::UnloggedBatch)
347 }
348 "COUNTER" => Ok(WriteType::Counter),
349 "BATCH_LOG" => Ok(WriteType::BatchLog),
350 _ => Err("Unexpected write type".into()),
351 })
352 }
353}
354
355#[derive(Debug)]
358pub struct AlreadyExistsError {
359 pub ks: CString,
362 pub table: CString,
364}
365
366impl FromCursor for AlreadyExistsError {
367 fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> error::Result<AlreadyExistsError> {
368 let ks = CString::from_cursor(&mut cursor)?;
369 let table = CString::from_cursor(&mut cursor)?;
370
371 Ok(AlreadyExistsError { ks: ks,
372 table: table, })
373 }
374}
375
376#[derive(Debug)]
381pub struct UnpreparedError {
382 pub id: CBytesShort,
384}
385
386impl FromCursor for UnpreparedError {
387 fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> error::Result<UnpreparedError> {
388 let id = CBytesShort::from_cursor(&mut cursor)?;
389
390 Ok(UnpreparedError { id: id })
391 }
392}