1#![warn(missing_docs)]
2use crate::error;
4use crate::frame::{FromBytes, FromCursor, Serialize, Version};
5use crate::types::*;
6use derive_more::Display;
7use std::convert::{From, TryFrom, TryInto};
8use std::default::Default;
9use std::io;
10use std::str::FromStr;
11
12#[derive(Debug, PartialEq, Clone, Copy, Display, Ord, PartialOrd, Eq, Hash, Default)]
16#[non_exhaustive]
17pub enum Consistency {
18 Any,
24 #[default]
28 One,
29 Two,
32 Three,
35 Quorum,
38 All,
42 LocalQuorum,
50 EachQuorum,
57 Serial,
63 LocalSerial,
67 LocalOne,
75}
76
77impl FromStr for Consistency {
78 type Err = error::Error;
79
80 fn from_str(s: &str) -> Result<Self, Self::Err> {
81 let consistency = match s {
82 "Any" => Consistency::Any,
83 "One" => Consistency::One,
84 "Two" => Consistency::Two,
85 "Three" => Consistency::Three,
86 "Quorum" => Consistency::Quorum,
87 "All" => Consistency::All,
88 "LocalQuorum" => Consistency::LocalQuorum,
89 "EachQuorum" => Consistency::EachQuorum,
90 "Serial" => Consistency::Serial,
91 "LocalSerial" => Consistency::LocalSerial,
92 "LocalOne" => Consistency::LocalOne,
93 _ => {
94 return Err(error::Error::General(format!(
95 "Invalid consistency provided: {s}"
96 )))
97 }
98 };
99
100 Ok(consistency)
101 }
102}
103
104impl Serialize for Consistency {
105 fn serialize(&self, cursor: &mut io::Cursor<&mut Vec<u8>>, version: Version) {
106 let value: i16 = (*self).into();
107 value.serialize(cursor, version)
108 }
109}
110
111impl TryFrom<CIntShort> for Consistency {
112 type Error = error::Error;
113
114 fn try_from(value: CIntShort) -> Result<Self, Self::Error> {
115 match value {
116 0x0000 => Ok(Consistency::Any),
117 0x0001 => Ok(Consistency::One),
118 0x0002 => Ok(Consistency::Two),
119 0x0003 => Ok(Consistency::Three),
120 0x0004 => Ok(Consistency::Quorum),
121 0x0005 => Ok(Consistency::All),
122 0x0006 => Ok(Consistency::LocalQuorum),
123 0x0007 => Ok(Consistency::EachQuorum),
124 0x0008 => Ok(Consistency::Serial),
125 0x0009 => Ok(Consistency::LocalSerial),
126 0x000A => Ok(Consistency::LocalOne),
127 _ => Err(Self::Error::UnknownConsistency(value)),
128 }
129 }
130}
131
132impl From<Consistency> for CIntShort {
133 fn from(value: Consistency) -> Self {
134 match value {
135 Consistency::Any => 0x0000,
136 Consistency::One => 0x0001,
137 Consistency::Two => 0x0002,
138 Consistency::Three => 0x0003,
139 Consistency::Quorum => 0x0004,
140 Consistency::All => 0x0005,
141 Consistency::LocalQuorum => 0x0006,
142 Consistency::EachQuorum => 0x0007,
143 Consistency::Serial => 0x0008,
144 Consistency::LocalSerial => 0x0009,
145 Consistency::LocalOne => 0x000A,
146 }
147 }
148}
149
150impl FromBytes for Consistency {
151 fn from_bytes(bytes: &[u8]) -> error::Result<Consistency> {
152 try_i16_from_bytes(bytes)
153 .map_err(Into::into)
154 .and_then(TryInto::try_into)
155 }
156}
157
158impl FromCursor for Consistency {
159 fn from_cursor(cursor: &mut io::Cursor<&[u8]>, version: Version) -> error::Result<Consistency> {
160 CIntShort::from_cursor(cursor, version).and_then(TryInto::try_into)
161 }
162}
163
164impl Consistency {
165 #[inline]
167 pub fn is_dc_local(self) -> bool {
168 matches!(
169 self,
170 Consistency::LocalOne | Consistency::LocalQuorum | Consistency::LocalSerial
171 )
172 }
173}
174
175#[cfg(test)]
176mod tests {
177 use super::*;
178 use crate::frame::traits::{FromBytes, FromCursor};
179 use std::io::Cursor;
180
181 #[test]
182 fn test_consistency_serialize() {
183 assert_eq!(Consistency::Any.serialize_to_vec(Version::V4), &[0, 0]);
184 assert_eq!(Consistency::One.serialize_to_vec(Version::V4), &[0, 1]);
185 assert_eq!(Consistency::Two.serialize_to_vec(Version::V4), &[0, 2]);
186 assert_eq!(Consistency::Three.serialize_to_vec(Version::V4), &[0, 3]);
187 assert_eq!(Consistency::Quorum.serialize_to_vec(Version::V4), &[0, 4]);
188 assert_eq!(Consistency::All.serialize_to_vec(Version::V4), &[0, 5]);
189 assert_eq!(
190 Consistency::LocalQuorum.serialize_to_vec(Version::V4),
191 &[0, 6]
192 );
193 assert_eq!(
194 Consistency::EachQuorum.serialize_to_vec(Version::V4),
195 &[0, 7]
196 );
197 assert_eq!(Consistency::Serial.serialize_to_vec(Version::V4), &[0, 8]);
198 assert_eq!(
199 Consistency::LocalSerial.serialize_to_vec(Version::V4),
200 &[0, 9]
201 );
202 assert_eq!(
203 Consistency::LocalOne.serialize_to_vec(Version::V4),
204 &[0, 10]
205 );
206 }
207
208 #[test]
209 fn test_consistency_from() {
210 assert_eq!(Consistency::try_from(0).unwrap(), Consistency::Any);
211 assert_eq!(Consistency::try_from(1).unwrap(), Consistency::One);
212 assert_eq!(Consistency::try_from(2).unwrap(), Consistency::Two);
213 assert_eq!(Consistency::try_from(3).unwrap(), Consistency::Three);
214 assert_eq!(Consistency::try_from(4).unwrap(), Consistency::Quorum);
215 assert_eq!(Consistency::try_from(5).unwrap(), Consistency::All);
216 assert_eq!(Consistency::try_from(6).unwrap(), Consistency::LocalQuorum);
217 assert_eq!(Consistency::try_from(7).unwrap(), Consistency::EachQuorum);
218 assert_eq!(Consistency::try_from(8).unwrap(), Consistency::Serial);
219 assert_eq!(Consistency::try_from(9).unwrap(), Consistency::LocalSerial);
220 assert_eq!(Consistency::try_from(10).unwrap(), Consistency::LocalOne);
221 }
222
223 #[test]
224 fn test_consistency_from_bytes() {
225 assert_eq!(Consistency::from_bytes(&[0, 0]).unwrap(), Consistency::Any);
226 assert_eq!(Consistency::from_bytes(&[0, 1]).unwrap(), Consistency::One);
227 assert_eq!(Consistency::from_bytes(&[0, 2]).unwrap(), Consistency::Two);
228 assert_eq!(
229 Consistency::from_bytes(&[0, 3]).unwrap(),
230 Consistency::Three
231 );
232 assert_eq!(
233 Consistency::from_bytes(&[0, 4]).unwrap(),
234 Consistency::Quorum
235 );
236 assert_eq!(Consistency::from_bytes(&[0, 5]).unwrap(), Consistency::All);
237 assert_eq!(
238 Consistency::from_bytes(&[0, 6]).unwrap(),
239 Consistency::LocalQuorum
240 );
241 assert_eq!(
242 Consistency::from_bytes(&[0, 7]).unwrap(),
243 Consistency::EachQuorum
244 );
245 assert_eq!(
246 Consistency::from_bytes(&[0, 8]).unwrap(),
247 Consistency::Serial
248 );
249 assert_eq!(
250 Consistency::from_bytes(&[0, 9]).unwrap(),
251 Consistency::LocalSerial
252 );
253 assert_eq!(
254 Consistency::from_bytes(&[0, 10]).unwrap(),
255 Consistency::LocalOne
256 );
257 assert!(Consistency::from_bytes(&[0, 11]).is_err());
258 }
259
260 #[test]
261 fn test_consistency_from_cursor() {
262 assert_eq!(
263 Consistency::from_cursor(&mut Cursor::new(&[0, 0]), Version::V4).unwrap(),
264 Consistency::Any
265 );
266 assert_eq!(
267 Consistency::from_cursor(&mut Cursor::new(&[0, 1]), Version::V4).unwrap(),
268 Consistency::One
269 );
270 assert_eq!(
271 Consistency::from_cursor(&mut Cursor::new(&[0, 2]), Version::V4).unwrap(),
272 Consistency::Two
273 );
274 assert_eq!(
275 Consistency::from_cursor(&mut Cursor::new(&[0, 3]), Version::V4).unwrap(),
276 Consistency::Three
277 );
278 assert_eq!(
279 Consistency::from_cursor(&mut Cursor::new(&[0, 4]), Version::V4).unwrap(),
280 Consistency::Quorum
281 );
282 assert_eq!(
283 Consistency::from_cursor(&mut Cursor::new(&[0, 5]), Version::V4).unwrap(),
284 Consistency::All
285 );
286 assert_eq!(
287 Consistency::from_cursor(&mut Cursor::new(&[0, 6]), Version::V4).unwrap(),
288 Consistency::LocalQuorum
289 );
290 assert_eq!(
291 Consistency::from_cursor(&mut Cursor::new(&[0, 7]), Version::V4).unwrap(),
292 Consistency::EachQuorum
293 );
294 assert_eq!(
295 Consistency::from_cursor(&mut Cursor::new(&[0, 8]), Version::V4).unwrap(),
296 Consistency::Serial
297 );
298 assert_eq!(
299 Consistency::from_cursor(&mut Cursor::new(&[0, 9]), Version::V4).unwrap(),
300 Consistency::LocalSerial
301 );
302 assert_eq!(
303 Consistency::from_cursor(&mut Cursor::new(&[0, 10]), Version::V4).unwrap(),
304 Consistency::LocalOne
305 );
306 }
307}