use std::io;
use std::result;
use crate::consistency::Consistency;
use crate::error;
use crate::frame::traits::FromCursor;
use crate::frame::Frame;
use crate::types::*;
pub type Result = result::Result<Frame, CDRSError>;
#[derive(Debug)]
pub struct CDRSError {
pub error_code: CInt,
pub message: CString,
pub additional_info: AdditionalErrorInfo,
}
impl FromCursor for CDRSError {
fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> error::Result<CDRSError> {
let error_code = CInt::from_cursor(&mut cursor)?;
let message = CString::from_cursor(&mut cursor)?;
let additional_info = AdditionalErrorInfo::from_cursor_with_code(&mut cursor, error_code)?;
Ok(CDRSError {
error_code: error_code,
message: message,
additional_info: additional_info,
})
}
}
#[derive(Debug)]
pub enum AdditionalErrorInfo {
Server(SimpleError),
Protocol(SimpleError),
Authentication(SimpleError),
Unavailable(UnavailableError),
Overloaded(SimpleError),
IsBootstrapping(SimpleError),
Truncate(SimpleError),
WriteTimeout(WriteTimeoutError),
ReadTimeout(ReadTimeoutError),
ReadFailure(ReadFailureError),
FunctionFailure(FunctionFailureError),
WriteFailure(WriteFailureError),
Syntax(SimpleError),
Unauthorized(SimpleError),
Invalid(SimpleError),
Config(SimpleError),
AlreadyExists(AlreadyExistsError),
Unprepared(UnpreparedError),
}
impl AdditionalErrorInfo {
pub fn from_cursor_with_code(
mut cursor: &mut io::Cursor<&[u8]>,
error_code: CInt,
) -> error::Result<AdditionalErrorInfo> {
match error_code {
0x0000 => Ok(AdditionalErrorInfo::Server(SimpleError::from_cursor(
&mut cursor,
)?)),
0x000A => Ok(AdditionalErrorInfo::Protocol(SimpleError::from_cursor(
&mut cursor,
)?)),
0x0100 => Ok(AdditionalErrorInfo::Authentication(
SimpleError::from_cursor(&mut cursor)?,
)),
0x1000 => Ok(AdditionalErrorInfo::Unavailable(
UnavailableError::from_cursor(&mut cursor)?,
)),
0x1001 => Ok(AdditionalErrorInfo::Overloaded(SimpleError::from_cursor(
&mut cursor,
)?)),
0x1002 => Ok(AdditionalErrorInfo::IsBootstrapping(
SimpleError::from_cursor(&mut cursor)?,
)),
0x1003 => Ok(AdditionalErrorInfo::Truncate(SimpleError::from_cursor(
&mut cursor,
)?)),
0x1100 => Ok(AdditionalErrorInfo::WriteTimeout(
WriteTimeoutError::from_cursor(&mut cursor)?,
)),
0x1200 => Ok(AdditionalErrorInfo::ReadTimeout(
ReadTimeoutError::from_cursor(&mut cursor)?,
)),
0x1300 => Ok(AdditionalErrorInfo::ReadFailure(
ReadFailureError::from_cursor(&mut cursor)?,
)),
0x1400 => Ok(AdditionalErrorInfo::FunctionFailure(
FunctionFailureError::from_cursor(&mut cursor)?,
)),
0x1500 => Ok(AdditionalErrorInfo::WriteFailure(
WriteFailureError::from_cursor(&mut cursor)?,
)),
0x2000 => Ok(AdditionalErrorInfo::Syntax(SimpleError::from_cursor(
&mut cursor,
)?)),
0x2100 => Ok(AdditionalErrorInfo::Unauthorized(SimpleError::from_cursor(
&mut cursor,
)?)),
0x2200 => Ok(AdditionalErrorInfo::Invalid(SimpleError::from_cursor(
&mut cursor,
)?)),
0x2300 => Ok(AdditionalErrorInfo::Config(SimpleError::from_cursor(
&mut cursor,
)?)),
0x2400 => Ok(AdditionalErrorInfo::AlreadyExists(
AlreadyExistsError::from_cursor(&mut cursor)?,
)),
0x2500 => Ok(AdditionalErrorInfo::Unprepared(
UnpreparedError::from_cursor(&mut cursor)?,
)),
_ => Err("Unexpected additional error info".into()),
}
}
}
#[derive(Debug)]
pub struct SimpleError {}
impl FromCursor for SimpleError {
fn from_cursor(mut _cursor: &mut io::Cursor<&[u8]>) -> error::Result<SimpleError> {
Ok(SimpleError {})
}
}
#[derive(Debug)]
pub struct UnavailableError {
pub cl: Consistency,
pub required: CInt,
pub alive: CInt,
}
impl FromCursor for UnavailableError {
fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> error::Result<UnavailableError> {
let cl = Consistency::from_cursor(&mut cursor)?;
let required = CInt::from_cursor(&mut cursor)?;
let alive = CInt::from_cursor(&mut cursor)?;
Ok(UnavailableError {
cl: cl,
required: required,
alive: alive,
})
}
}
#[derive(Debug)]
pub struct WriteTimeoutError {
pub cl: Consistency,
pub received: CInt,
pub blockfor: CInt,
pub write_type: WriteType,
}
impl FromCursor for WriteTimeoutError {
fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> error::Result<WriteTimeoutError> {
let cl = Consistency::from_cursor(&mut cursor)?;
let received = CInt::from_cursor(&mut cursor)?;
let blockfor = CInt::from_cursor(&mut cursor)?;
let write_type = WriteType::from_cursor(&mut cursor)?;
Ok(WriteTimeoutError {
cl: cl,
received: received,
blockfor: blockfor,
write_type: write_type,
})
}
}
#[derive(Debug)]
pub struct ReadTimeoutError {
pub cl: Consistency,
pub received: CInt,
pub blockfor: CInt,
data_present: u8,
}
impl ReadTimeoutError {
pub fn replica_has_responded(&self) -> bool {
self.data_present != 0
}
}
impl FromCursor for ReadTimeoutError {
fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> error::Result<ReadTimeoutError> {
let cl = Consistency::from_cursor(&mut cursor)?;
let received = CInt::from_cursor(&mut cursor)?;
let blockfor = CInt::from_cursor(&mut cursor)?;
let data_present = try_from_bytes(cursor_next_value(&mut cursor, 1)?.as_slice())? as u8;
Ok(ReadTimeoutError {
cl: cl,
received: received,
blockfor: blockfor,
data_present: data_present,
})
}
}
#[derive(Debug)]
pub struct ReadFailureError {
pub cl: Consistency,
pub received: CInt,
pub blockfor: CInt,
pub num_failures: CInt,
data_present: u8,
}
impl ReadFailureError {
pub fn replica_has_responded(&self) -> bool {
self.data_present != 0
}
}
impl FromCursor for ReadFailureError {
fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> error::Result<ReadFailureError> {
let cl = Consistency::from_cursor(&mut cursor)?;
let received = CInt::from_cursor(&mut cursor)?;
let blockfor = CInt::from_cursor(&mut cursor)?;
let num_failures = CInt::from_cursor(&mut cursor)?;
let data_present = try_from_bytes(cursor_next_value(&mut cursor, 1)?.as_slice())? as u8;
Ok(ReadFailureError {
cl: cl,
received: received,
blockfor: blockfor,
num_failures: num_failures,
data_present: data_present,
})
}
}
#[derive(Debug)]
pub struct FunctionFailureError {
pub keyspace: CString,
pub function: CString,
pub arg_types: CStringList,
}
impl FromCursor for FunctionFailureError {
fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> error::Result<FunctionFailureError> {
let keyspace = CString::from_cursor(&mut cursor)?;
let function = CString::from_cursor(&mut cursor)?;
let arg_types = CStringList::from_cursor(&mut cursor)?;
Ok(FunctionFailureError {
keyspace: keyspace,
function: function,
arg_types: arg_types,
})
}
}
#[derive(Debug)]
pub struct WriteFailureError {
pub cl: Consistency,
pub received: CInt,
pub blockfor: CInt,
pub num_failures: CInt,
pub write_type: WriteType,
}
impl FromCursor for WriteFailureError {
fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> error::Result<WriteFailureError> {
let cl = Consistency::from_cursor(&mut cursor)?;
let received = CInt::from_cursor(&mut cursor)?;
let blockfor = CInt::from_cursor(&mut cursor)?;
let num_failures = CInt::from_cursor(&mut cursor)?;
let write_type = WriteType::from_cursor(&mut cursor)?;
Ok(WriteFailureError {
cl: cl,
received: received,
blockfor: blockfor,
num_failures: num_failures,
write_type: write_type,
})
}
}
#[derive(Debug)]
pub enum WriteType {
Simple,
Batch,
UnloggedBatch,
Counter,
BatchLog,
}
impl FromCursor for WriteType {
fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> error::Result<WriteType> {
CString::from_cursor(&mut cursor).and_then(|wt| match wt.as_str() {
"SIMPLE" => Ok(WriteType::Simple),
"BATCH" => Ok(WriteType::Batch),
"UNLOGGED_BATCH" => Ok(WriteType::UnloggedBatch),
"COUNTER" => Ok(WriteType::Counter),
"BATCH_LOG" => Ok(WriteType::BatchLog),
_ => Err("Unexpected write type".into()),
})
}
}
#[derive(Debug)]
pub struct AlreadyExistsError {
pub ks: CString,
pub table: CString,
}
impl FromCursor for AlreadyExistsError {
fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> error::Result<AlreadyExistsError> {
let ks = CString::from_cursor(&mut cursor)?;
let table = CString::from_cursor(&mut cursor)?;
Ok(AlreadyExistsError {
ks: ks,
table: table,
})
}
}
#[derive(Debug)]
pub struct UnpreparedError {
pub id: CBytesShort,
}
impl FromCursor for UnpreparedError {
fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> error::Result<UnpreparedError> {
let id = CBytesShort::from_cursor(&mut cursor)?;
Ok(UnpreparedError { id: id })
}
}