Skip to main content

kevy_store/
cond.rs

1//! Named arguments for the command flags the store takes: write
2//! conditions, list ends and positions, and score comparisons.
3
4/// When a write may happen, judged by whether its target already exists:
5/// `SET`'s and `ZADD`'s `NX` / `XX`. One value instead of two flags, so
6/// asking for both is not expressible.
7///
8/// ```
9/// use kevy_store::{SetCondition, Store};
10/// let mut s = Store::new();
11/// assert!(!s.set(b"k", b"1".to_vec(), None, SetCondition::IfPresent));
12/// assert!(s.set(b"k", b"1".to_vec(), None, SetCondition::IfAbsent));
13/// assert!(!s.set(b"k", b"2".to_vec(), None, SetCondition::IfAbsent));
14/// assert!(s.set(b"k", b"2".to_vec(), None, SetCondition::Always));
15/// ```
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
17#[non_exhaustive]
18pub enum SetCondition {
19    /// Write whether or not the target exists.
20    ///
21    /// ```
22    /// use kevy_store::{SetCondition, Store};
23    /// let mut s = Store::new();
24    /// assert!(s.set(b"k", b"1".to_vec(), None, SetCondition::Always));
25    /// assert!(s.set(b"k", b"2".to_vec(), None, SetCondition::Always));
26    /// assert_eq!(s.get(b"k")?.as_deref(), Some(&b"2"[..]));
27    /// # Ok::<(), kevy_store::StoreError>(())
28    /// ```
29    #[default]
30    Always,
31    /// `NX`: write only when the target does not exist.
32    ///
33    /// ```
34    /// use kevy_store::{SetCondition, Store};
35    /// let mut s = Store::new();
36    /// assert!(s.set(b"k", b"1".to_vec(), None, SetCondition::IfAbsent));
37    /// assert!(!s.set(b"k", b"2".to_vec(), None, SetCondition::IfAbsent));
38    /// assert_eq!(s.get(b"k")?.as_deref(), Some(&b"1"[..]));
39    /// # Ok::<(), kevy_store::StoreError>(())
40    /// ```
41    IfAbsent,
42    /// `XX`: write only when the target already exists.
43    ///
44    /// ```
45    /// use kevy_store::{SetCondition, Store};
46    /// let mut s = Store::new();
47    /// assert!(!s.set(b"k", b"1".to_vec(), None, SetCondition::IfPresent));
48    /// assert_eq!(s.get(b"k")?, None);
49    /// # Ok::<(), kevy_store::StoreError>(())
50    /// ```
51    IfPresent,
52}
53
54/// One end of a list: `LEFT` (the head, index 0) or `RIGHT` (the tail).
55///
56/// ```
57/// use kevy_store::{ListEnd, Store};
58/// let mut s = Store::new();
59/// s.rpush(b"src", &[b"a".as_slice(), b"b".as_slice()]).unwrap();
60/// let moved = s.lmove(b"src", b"dst", ListEnd::Right, ListEnd::Left).unwrap();
61/// assert_eq!(moved.as_deref(), Some(&b"b"[..]));
62/// ```
63#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
64pub enum ListEnd {
65    /// The head: `LPUSH` / `LPOP` side.
66    ///
67    /// ```
68    /// use kevy_store::{ListEnd, Store};
69    /// let mut s = Store::new();
70    /// s.rpush(b"src", &[b"a".as_slice(), b"b".as_slice()])?;
71    /// let moved = s.lmove(b"src", b"dst", ListEnd::Left, ListEnd::Left)?;
72    /// assert_eq!(moved.as_deref(), Some(&b"a"[..]));
73    /// # Ok::<(), kevy_store::StoreError>(())
74    /// ```
75    Left,
76    /// The tail: `RPUSH` / `RPOP` side.
77    ///
78    /// ```
79    /// use kevy_store::{ListEnd, Store};
80    /// let mut s = Store::new();
81    /// s.rpush(b"src", &[b"a".as_slice(), b"b".as_slice()])?;
82    /// s.lmove(b"src", b"dst", ListEnd::Right, ListEnd::Right)?;
83    /// s.lmove(b"src", b"dst", ListEnd::Right, ListEnd::Right)?;
84    /// assert_eq!(s.lrange(b"dst", 0, -1)?, [b"b".to_vec(), b"a".to_vec()]);
85    /// # Ok::<(), kevy_store::StoreError>(())
86    /// ```
87    Right,
88}
89
90/// Where `LINSERT` places the new element relative to its pivot.
91///
92/// ```
93/// use kevy_store::{InsertPosition, Store};
94/// let mut s = Store::new();
95/// s.rpush(b"l", &[b"a".as_slice(), b"c".as_slice()]).unwrap();
96/// assert_eq!(s.linsert(b"l", InsertPosition::Before, b"c", b"b").unwrap(), 3);
97/// assert_eq!(s.lrange(b"l", 0, -1).unwrap(), [b"a".to_vec(), b"b".to_vec(), b"c".to_vec()]);
98/// ```
99#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
100pub enum InsertPosition {
101    /// Immediately before the pivot.
102    ///
103    /// ```
104    /// use kevy_store::{InsertPosition, Store};
105    /// let mut s = Store::new();
106    /// s.rpush(b"l", &[b"b".as_slice()])?;
107    /// s.linsert(b"l", InsertPosition::Before, b"b", b"a")?;
108    /// assert_eq!(s.lrange(b"l", 0, -1)?, [b"a".to_vec(), b"b".to_vec()]);
109    /// # Ok::<(), kevy_store::StoreError>(())
110    /// ```
111    Before,
112    /// Immediately after the pivot.
113    ///
114    /// ```
115    /// use kevy_store::{InsertPosition, Store};
116    /// let mut s = Store::new();
117    /// s.rpush(b"l", &[b"a".as_slice()])?;
118    /// s.linsert(b"l", InsertPosition::After, b"a", b"b")?;
119    /// assert_eq!(s.lrange(b"l", 0, -1)?, [b"a".to_vec(), b"b".to_vec()]);
120    /// # Ok::<(), kevy_store::StoreError>(())
121    /// ```
122    After,
123}
124
125/// Which score change a conditional `ZADD` accepts for an existing
126/// member: `GT` / `LT`, or any. New members are not judged by it.
127///
128/// ```
129/// use kevy_store::{ScoreCompare, SetCondition, ZaddFlags};
130/// let gt = ZaddFlags::new(SetCondition::Always, ScoreCompare::Greater).unwrap();
131/// assert_eq!(gt.compare(), ScoreCompare::Greater);
132/// ```
133#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
134#[non_exhaustive]
135pub enum ScoreCompare {
136    /// Any new score replaces the old one.
137    ///
138    /// ```
139    /// use kevy_store::{ScoreCompare, SetCondition, Store, ZaddFlags};
140    /// let mut s = Store::new();
141    /// let any = ZaddFlags::new(SetCondition::Always, ScoreCompare::Any).unwrap();
142    /// s.zadd(b"z", &[(5.0, b"m".as_slice())])?;
143    /// s.zadd_flags(b"z", &[(1.0, b"m".as_slice())], any)?;
144    /// assert_eq!(s.zscore(b"z", b"m")?, Some(1.0));
145    /// # Ok::<(), kevy_store::StoreError>(())
146    /// ```
147    #[default]
148    Any,
149    /// `GT`: only a greater score replaces the old one.
150    ///
151    /// ```
152    /// use kevy_store::{ScoreCompare, SetCondition, Store, ZaddFlags};
153    /// let mut s = Store::new();
154    /// let gt = ZaddFlags::new(SetCondition::Always, ScoreCompare::Greater).unwrap();
155    /// s.zadd(b"z", &[(5.0, b"m".as_slice())])?;
156    /// s.zadd_flags(b"z", &[(1.0, b"m".as_slice())], gt)?;
157    /// assert_eq!(s.zscore(b"z", b"m")?, Some(5.0));
158    /// s.zadd_flags(b"z", &[(9.0, b"m".as_slice())], gt)?;
159    /// assert_eq!(s.zscore(b"z", b"m")?, Some(9.0));
160    /// # Ok::<(), kevy_store::StoreError>(())
161    /// ```
162    Greater,
163    /// `LT`: only a lesser score replaces the old one.
164    ///
165    /// ```
166    /// use kevy_store::{ScoreCompare, SetCondition, Store, ZaddFlags};
167    /// let mut s = Store::new();
168    /// let lt = ZaddFlags::new(SetCondition::Always, ScoreCompare::Less).unwrap();
169    /// s.zadd(b"z", &[(5.0, b"m".as_slice())])?;
170    /// s.zadd_flags(b"z", &[(9.0, b"m".as_slice())], lt)?;
171    /// assert_eq!(s.zscore(b"z", b"m")?, Some(5.0));
172    /// # Ok::<(), kevy_store::StoreError>(())
173    /// ```
174    Less,
175}