cassandra_proto/
consistency.rs

1#![warn(missing_docs)]
2//! The module contains Rust representation of Cassandra consistency levels.
3use std::convert::From;
4use std::default::Default;
5use std::io;
6
7use crate::error;
8use crate::frame::{FromBytes, FromCursor, IntoBytes};
9use crate::types::*;
10
11/// `Consistency` is an enum which represents Cassandra's consistency levels.
12/// To find more details about each consistency level please refer to Cassandra official docs.
13#[derive(Debug, PartialEq, Clone, Copy)]
14pub enum Consistency {
15    /// A write must be written to the commit log and memtable on all replica nodes in the cluster
16    /// for that partition key.	Provides the highest consistency
17    /// and the lowest availability of any other level.
18    Any,
19    ///
20    /// A write must be written to the commit log and memtable of at least one replica node.
21    /// Satisfies the needs of most users because consistency requirements are not stringent.
22    One,
23    /// A write must be written to the commit log and memtable of at least two replica nodes.
24    /// Similar to ONE.
25    Two,
26    /// A write must be written to the commit log and memtable of at least three replica nodes.
27    /// Similar to TWO.
28    Three,
29    /// A write must be written to the commit log and memtable on a quorum of replica nodes.
30    /// Provides strong consistency if you can tolerate some level of failure.
31    Quorum,
32    /// A write must be written to the commit log and memtable on all replica nodes in the cluster
33    /// for that partition key.
34    /// Provides the highest consistency and the lowest availability of any other level.
35    All,
36    /// Strong consistency. A write must be written to the commit log and memtable on a quorum
37    /// of replica nodes in the same data center as thecoordinator node.
38    /// Avoids latency of inter-data center communication.
39    /// Used in multiple data center clusters with a rack-aware replica placement strategy,
40    /// such as NetworkTopologyStrategy, and a properly configured snitch.
41    /// Use to maintain consistency locally (within the single data center).
42    /// Can be used with SimpleStrategy.
43    LocalQuorum,
44    /// Strong consistency. A write must be written to the commit log and memtable on a quorum of
45    /// replica nodes in all data center.
46    /// Used in multiple data center clusters to strictly maintain consistency at the same level
47    /// in each data center. For example, choose this level
48    /// if you want a read to fail when a data center is down and the QUORUM
49    /// cannot be reached on that data center.
50    EachQuorum,
51    /// Achieves linearizable consistency for lightweight transactions by preventing unconditional
52    /// updates.	You cannot configure this level as a normal consistency level,
53    /// configured at the driver level using the consistency level field.
54    /// You configure this level using the serial consistency field
55    /// as part of the native protocol operation. See failure scenarios.
56    Serial,
57    /// Same as SERIAL but confined to the data center. A write must be written conditionally
58    /// to the commit log and memtable on a quorum of replica nodes in the same data center.
59    /// Same as SERIAL. Used for disaster recovery. See failure scenarios.
60    LocalSerial,
61    /// A write must be sent to, and successfully acknowledged by,
62    /// at least one replica node in the local data center.
63    /// In a multiple data center clusters, a consistency level of ONE is often desirable,
64    /// but cross-DC traffic is not. LOCAL_ONE accomplishes this.
65    /// For security and quality reasons, you can use this consistency level
66    /// in an offline datacenter to prevent automatic connection
67    /// to online nodes in other data centers if an offline node goes down.
68    LocalOne,
69    /// This is an error scenario either the client code doesn't support it or server is sending
70    /// bad headers
71    Unknown,
72}
73
74impl Default for Consistency {
75    fn default() -> Consistency {
76        Consistency::One
77    }
78}
79
80impl IntoBytes for Consistency {
81    fn into_cbytes(&self) -> Vec<u8> {
82        match *self {
83            Consistency::Any => to_short(0x0000),
84            Consistency::One => to_short(0x0001),
85            Consistency::Two => to_short(0x0002),
86            Consistency::Three => to_short(0x0003),
87            Consistency::Quorum => to_short(0x0004),
88            Consistency::All => to_short(0x0005),
89            Consistency::LocalQuorum => to_short(0x0006),
90            Consistency::EachQuorum => to_short(0x0007),
91            Consistency::Serial => to_short(0x0008),
92            Consistency::LocalSerial => to_short(0x0009),
93            Consistency::LocalOne => to_short(0x000A),
94            Consistency::Unknown => to_short(0x0063),
95            // giving Unknown a value of 99
96        }
97    }
98}
99
100impl From<i32> for Consistency {
101    fn from(bytes: i32) -> Consistency {
102        match bytes {
103            0x0000 => Consistency::Any,
104            0x0001 => Consistency::One,
105            0x0002 => Consistency::Two,
106            0x0003 => Consistency::Three,
107            0x0004 => Consistency::Quorum,
108            0x0005 => Consistency::All,
109            0x0006 => Consistency::LocalQuorum,
110            0x0007 => Consistency::EachQuorum,
111            0x0008 => Consistency::Serial,
112            0x0009 => Consistency::LocalSerial,
113            0x000A => Consistency::LocalOne,
114            _ => Consistency::Unknown,
115        }
116    }
117}
118
119impl FromBytes for Consistency {
120    fn from_bytes(bytes: &[u8]) -> error::Result<Consistency> {
121        try_from_bytes(bytes).map_err(Into::into).map(|b| match b {
122            0x0000 => Consistency::Any,
123            0x0001 => Consistency::One,
124            0x0002 => Consistency::Two,
125            0x0003 => Consistency::Three,
126            0x0004 => Consistency::Quorum,
127            0x0005 => Consistency::All,
128            0x0006 => Consistency::LocalQuorum,
129            0x0007 => Consistency::EachQuorum,
130            0x0008 => Consistency::Serial,
131            0x0009 => Consistency::LocalSerial,
132            0x000A => Consistency::LocalOne,
133            _ => Consistency::Unknown,
134        })
135    }
136}
137
138impl FromCursor for Consistency {
139    fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> error::Result<Consistency> {
140        let consistency_num = CIntShort::from_cursor(&mut cursor)? as i32;
141        Ok(Consistency::from(consistency_num))
142    }
143}
144
145#[cfg(test)]
146mod tests {
147    use super::*;
148    use crate::frame::traits::{FromBytes, FromCursor, IntoBytes};
149    use std::io::Cursor;
150
151    #[test]
152    fn test_consistency_into_cbytes() {
153        assert_eq!(Consistency::Any.into_cbytes(), &[0, 0]);
154        assert_eq!(Consistency::One.into_cbytes(), &[0, 1]);
155        assert_eq!(Consistency::Two.into_cbytes(), &[0, 2]);
156        assert_eq!(Consistency::Three.into_cbytes(), &[0, 3]);
157        assert_eq!(Consistency::Quorum.into_cbytes(), &[0, 4]);
158        assert_eq!(Consistency::All.into_cbytes(), &[0, 5]);
159        assert_eq!(Consistency::LocalQuorum.into_cbytes(), &[0, 6]);
160        assert_eq!(Consistency::EachQuorum.into_cbytes(), &[0, 7]);
161        assert_eq!(Consistency::Serial.into_cbytes(), &[0, 8]);
162        assert_eq!(Consistency::LocalSerial.into_cbytes(), &[0, 9]);
163        assert_eq!(Consistency::LocalOne.into_cbytes(), &[0, 10]);
164        assert_eq!(Consistency::Unknown.into_cbytes(), &[0, 99]);
165    }
166
167    #[test]
168    fn test_consistency_from() {
169        assert_eq!(Consistency::from(0), Consistency::Any);
170        assert_eq!(Consistency::from(1), Consistency::One);
171        assert_eq!(Consistency::from(2), Consistency::Two);
172        assert_eq!(Consistency::from(3), Consistency::Three);
173        assert_eq!(Consistency::from(4), Consistency::Quorum);
174        assert_eq!(Consistency::from(5), Consistency::All);
175        assert_eq!(Consistency::from(6), Consistency::LocalQuorum);
176        assert_eq!(Consistency::from(7), Consistency::EachQuorum);
177        assert_eq!(Consistency::from(8), Consistency::Serial);
178        assert_eq!(Consistency::from(9), Consistency::LocalSerial);
179        assert_eq!(Consistency::from(10), Consistency::LocalOne);
180        assert_eq!(Consistency::from(11), Consistency::Unknown);
181    }
182
183    #[test]
184    fn test_consistency_from_bytes() {
185        assert_eq!(Consistency::from_bytes(&[0, 0]).unwrap(), Consistency::Any);
186        assert_eq!(Consistency::from_bytes(&[0, 1]).unwrap(), Consistency::One);
187        assert_eq!(Consistency::from_bytes(&[0, 2]).unwrap(), Consistency::Two);
188        assert_eq!(
189            Consistency::from_bytes(&[0, 3]).unwrap(),
190            Consistency::Three
191        );
192        assert_eq!(
193            Consistency::from_bytes(&[0, 4]).unwrap(),
194            Consistency::Quorum
195        );
196        assert_eq!(Consistency::from_bytes(&[0, 5]).unwrap(), Consistency::All);
197        assert_eq!(
198            Consistency::from_bytes(&[0, 6]).unwrap(),
199            Consistency::LocalQuorum
200        );
201        assert_eq!(
202            Consistency::from_bytes(&[0, 7]).unwrap(),
203            Consistency::EachQuorum
204        );
205        assert_eq!(
206            Consistency::from_bytes(&[0, 8]).unwrap(),
207            Consistency::Serial
208        );
209        assert_eq!(
210            Consistency::from_bytes(&[0, 9]).unwrap(),
211            Consistency::LocalSerial
212        );
213        assert_eq!(
214            Consistency::from_bytes(&[0, 10]).unwrap(),
215            Consistency::LocalOne
216        );
217        assert_eq!(
218            Consistency::from_bytes(&[0, 11]).unwrap(),
219            Consistency::Unknown
220        );
221    }
222
223    #[test]
224    fn test_consistency_from_cursor() {
225        assert_eq!(
226            Consistency::from_cursor(&mut Cursor::new(&[0, 0])).unwrap(),
227            Consistency::Any
228        );
229        assert_eq!(
230            Consistency::from_cursor(&mut Cursor::new(&[0, 1])).unwrap(),
231            Consistency::One
232        );
233        assert_eq!(
234            Consistency::from_cursor(&mut Cursor::new(&[0, 2])).unwrap(),
235            Consistency::Two
236        );
237        assert_eq!(
238            Consistency::from_cursor(&mut Cursor::new(&[0, 3])).unwrap(),
239            Consistency::Three
240        );
241        assert_eq!(
242            Consistency::from_cursor(&mut Cursor::new(&[0, 4])).unwrap(),
243            Consistency::Quorum
244        );
245        assert_eq!(
246            Consistency::from_cursor(&mut Cursor::new(&[0, 5])).unwrap(),
247            Consistency::All
248        );
249        assert_eq!(
250            Consistency::from_cursor(&mut Cursor::new(&[0, 6])).unwrap(),
251            Consistency::LocalQuorum
252        );
253        assert_eq!(
254            Consistency::from_cursor(&mut Cursor::new(&[0, 7])).unwrap(),
255            Consistency::EachQuorum
256        );
257        assert_eq!(
258            Consistency::from_cursor(&mut Cursor::new(&[0, 8])).unwrap(),
259            Consistency::Serial
260        );
261        assert_eq!(
262            Consistency::from_cursor(&mut Cursor::new(&[0, 9])).unwrap(),
263            Consistency::LocalSerial
264        );
265        assert_eq!(
266            Consistency::from_cursor(&mut Cursor::new(&[0, 10])).unwrap(),
267            Consistency::LocalOne
268        );
269    }
270
271}