#![warn(missing_docs)]
use crate::error;
use crate::frame::{FromBytes, FromCursor, Serialize, Version};
use crate::types::*;
use derive_more::Display;
use std::convert::{From, TryFrom, TryInto};
use std::default::Default;
use std::io;
use std::str::FromStr;
#[derive(Debug, PartialEq, Clone, Copy, Display, Ord, PartialOrd, Eq, Hash, Default)]
#[non_exhaustive]
pub enum Consistency {
Any,
#[default]
One,
Two,
Three,
Quorum,
All,
LocalQuorum,
EachQuorum,
Serial,
LocalSerial,
LocalOne,
}
impl FromStr for Consistency {
type Err = error::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let consistency = match s {
"Any" => Consistency::Any,
"One" => Consistency::One,
"Two" => Consistency::Two,
"Three" => Consistency::Three,
"Quorum" => Consistency::Quorum,
"All" => Consistency::All,
"LocalQuorum" => Consistency::LocalQuorum,
"EachQuorum" => Consistency::EachQuorum,
"Serial" => Consistency::Serial,
"LocalSerial" => Consistency::LocalSerial,
"LocalOne" => Consistency::LocalOne,
_ => {
return Err(error::Error::General(format!(
"Invalid consistency provided: {s}"
)))
}
};
Ok(consistency)
}
}
impl Serialize for Consistency {
fn serialize(&self, cursor: &mut io::Cursor<&mut Vec<u8>>, version: Version) {
let value: i16 = (*self).into();
value.serialize(cursor, version)
}
}
impl TryFrom<CIntShort> for Consistency {
type Error = error::Error;
fn try_from(value: CIntShort) -> Result<Self, Self::Error> {
match value {
0x0000 => Ok(Consistency::Any),
0x0001 => Ok(Consistency::One),
0x0002 => Ok(Consistency::Two),
0x0003 => Ok(Consistency::Three),
0x0004 => Ok(Consistency::Quorum),
0x0005 => Ok(Consistency::All),
0x0006 => Ok(Consistency::LocalQuorum),
0x0007 => Ok(Consistency::EachQuorum),
0x0008 => Ok(Consistency::Serial),
0x0009 => Ok(Consistency::LocalSerial),
0x000A => Ok(Consistency::LocalOne),
_ => Err(Self::Error::UnknownConsistency(value)),
}
}
}
impl From<Consistency> for CIntShort {
fn from(value: Consistency) -> Self {
match value {
Consistency::Any => 0x0000,
Consistency::One => 0x0001,
Consistency::Two => 0x0002,
Consistency::Three => 0x0003,
Consistency::Quorum => 0x0004,
Consistency::All => 0x0005,
Consistency::LocalQuorum => 0x0006,
Consistency::EachQuorum => 0x0007,
Consistency::Serial => 0x0008,
Consistency::LocalSerial => 0x0009,
Consistency::LocalOne => 0x000A,
}
}
}
impl FromBytes for Consistency {
fn from_bytes(bytes: &[u8]) -> error::Result<Consistency> {
try_i16_from_bytes(bytes)
.map_err(Into::into)
.and_then(TryInto::try_into)
}
}
impl FromCursor for Consistency {
fn from_cursor(cursor: &mut io::Cursor<&[u8]>, version: Version) -> error::Result<Consistency> {
CIntShort::from_cursor(cursor, version).and_then(TryInto::try_into)
}
}
impl Consistency {
#[inline]
pub fn is_dc_local(self) -> bool {
matches!(
self,
Consistency::LocalOne | Consistency::LocalQuorum | Consistency::LocalSerial
)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::frame::traits::{FromBytes, FromCursor};
use std::io::Cursor;
#[test]
fn test_consistency_serialize() {
assert_eq!(Consistency::Any.serialize_to_vec(Version::V4), &[0, 0]);
assert_eq!(Consistency::One.serialize_to_vec(Version::V4), &[0, 1]);
assert_eq!(Consistency::Two.serialize_to_vec(Version::V4), &[0, 2]);
assert_eq!(Consistency::Three.serialize_to_vec(Version::V4), &[0, 3]);
assert_eq!(Consistency::Quorum.serialize_to_vec(Version::V4), &[0, 4]);
assert_eq!(Consistency::All.serialize_to_vec(Version::V4), &[0, 5]);
assert_eq!(
Consistency::LocalQuorum.serialize_to_vec(Version::V4),
&[0, 6]
);
assert_eq!(
Consistency::EachQuorum.serialize_to_vec(Version::V4),
&[0, 7]
);
assert_eq!(Consistency::Serial.serialize_to_vec(Version::V4), &[0, 8]);
assert_eq!(
Consistency::LocalSerial.serialize_to_vec(Version::V4),
&[0, 9]
);
assert_eq!(
Consistency::LocalOne.serialize_to_vec(Version::V4),
&[0, 10]
);
}
#[test]
fn test_consistency_from() {
assert_eq!(Consistency::try_from(0).unwrap(), Consistency::Any);
assert_eq!(Consistency::try_from(1).unwrap(), Consistency::One);
assert_eq!(Consistency::try_from(2).unwrap(), Consistency::Two);
assert_eq!(Consistency::try_from(3).unwrap(), Consistency::Three);
assert_eq!(Consistency::try_from(4).unwrap(), Consistency::Quorum);
assert_eq!(Consistency::try_from(5).unwrap(), Consistency::All);
assert_eq!(Consistency::try_from(6).unwrap(), Consistency::LocalQuorum);
assert_eq!(Consistency::try_from(7).unwrap(), Consistency::EachQuorum);
assert_eq!(Consistency::try_from(8).unwrap(), Consistency::Serial);
assert_eq!(Consistency::try_from(9).unwrap(), Consistency::LocalSerial);
assert_eq!(Consistency::try_from(10).unwrap(), Consistency::LocalOne);
}
#[test]
fn test_consistency_from_bytes() {
assert_eq!(Consistency::from_bytes(&[0, 0]).unwrap(), Consistency::Any);
assert_eq!(Consistency::from_bytes(&[0, 1]).unwrap(), Consistency::One);
assert_eq!(Consistency::from_bytes(&[0, 2]).unwrap(), Consistency::Two);
assert_eq!(
Consistency::from_bytes(&[0, 3]).unwrap(),
Consistency::Three
);
assert_eq!(
Consistency::from_bytes(&[0, 4]).unwrap(),
Consistency::Quorum
);
assert_eq!(Consistency::from_bytes(&[0, 5]).unwrap(), Consistency::All);
assert_eq!(
Consistency::from_bytes(&[0, 6]).unwrap(),
Consistency::LocalQuorum
);
assert_eq!(
Consistency::from_bytes(&[0, 7]).unwrap(),
Consistency::EachQuorum
);
assert_eq!(
Consistency::from_bytes(&[0, 8]).unwrap(),
Consistency::Serial
);
assert_eq!(
Consistency::from_bytes(&[0, 9]).unwrap(),
Consistency::LocalSerial
);
assert_eq!(
Consistency::from_bytes(&[0, 10]).unwrap(),
Consistency::LocalOne
);
assert!(Consistency::from_bytes(&[0, 11]).is_err());
}
#[test]
fn test_consistency_from_cursor() {
assert_eq!(
Consistency::from_cursor(&mut Cursor::new(&[0, 0]), Version::V4).unwrap(),
Consistency::Any
);
assert_eq!(
Consistency::from_cursor(&mut Cursor::new(&[0, 1]), Version::V4).unwrap(),
Consistency::One
);
assert_eq!(
Consistency::from_cursor(&mut Cursor::new(&[0, 2]), Version::V4).unwrap(),
Consistency::Two
);
assert_eq!(
Consistency::from_cursor(&mut Cursor::new(&[0, 3]), Version::V4).unwrap(),
Consistency::Three
);
assert_eq!(
Consistency::from_cursor(&mut Cursor::new(&[0, 4]), Version::V4).unwrap(),
Consistency::Quorum
);
assert_eq!(
Consistency::from_cursor(&mut Cursor::new(&[0, 5]), Version::V4).unwrap(),
Consistency::All
);
assert_eq!(
Consistency::from_cursor(&mut Cursor::new(&[0, 6]), Version::V4).unwrap(),
Consistency::LocalQuorum
);
assert_eq!(
Consistency::from_cursor(&mut Cursor::new(&[0, 7]), Version::V4).unwrap(),
Consistency::EachQuorum
);
assert_eq!(
Consistency::from_cursor(&mut Cursor::new(&[0, 8]), Version::V4).unwrap(),
Consistency::Serial
);
assert_eq!(
Consistency::from_cursor(&mut Cursor::new(&[0, 9]), Version::V4).unwrap(),
Consistency::LocalSerial
);
assert_eq!(
Consistency::from_cursor(&mut Cursor::new(&[0, 10]), Version::V4).unwrap(),
Consistency::LocalOne
);
}
}