kevy_embedded/
ops_bonus.rs1use crate::{KevyError, KevyResult};
7
8use crate::store::ensure_writable;
9use crate::store::{Store, commit_write, store_err};
10
11impl Store {
12 pub fn setnx(&self, key: &[u8], value: &[u8]) -> KevyResult<bool> {
18 ensure_writable(self)?;
19 let mut g = self.wshard(key);
20 let ok = g.store.set(key, value.to_vec(), None, true, false);
21 if ok {
22 commit_write(&mut g, &[b"SET", key, value, b"NX"])?;
23 }
24 Ok(ok)
25 }
26
27 pub fn incrbyfloat(&self, key: &[u8], delta: f64) -> KevyResult<f64> {
30 ensure_writable(self)?;
31 let mut g = self.wshard(key);
32 let new_bytes = g.store.incr_by_float(key, delta).map_err(store_err)?;
33 let delta_str = format!("{delta}");
34 commit_write(&mut g, &[b"INCRBYFLOAT", key, delta_str.as_bytes()])?;
35 std::str::from_utf8(&new_bytes)
36 .ok()
37 .and_then(|s| s.parse::<f64>().ok())
38 .ok_or_else(|| KevyError::Protocol("incrbyfloat result not parseable".into()))
39 }
40
41 pub fn decr(&self, key: &[u8]) -> KevyResult<i64> {
43 self.incr_by(key, -1)
44 }
45
46 pub fn decrby(&self, key: &[u8], delta: i64) -> KevyResult<i64> {
48 self.incr_by(key, delta.checked_neg().unwrap_or(i64::MIN.saturating_add(1)))
49 }
50
51 pub fn strlen(&self, key: &[u8]) -> KevyResult<usize> {
54 self.wshard(key).store.strlen(key).map_err(store_err)
55 }
56
57 pub fn append(&self, key: &[u8], data: &[u8]) -> KevyResult<usize> {
60 ensure_writable(self)?;
61 let mut g = self.wshard(key);
62 let new_len = g.store.append(key, data).map_err(store_err)?;
63 commit_write(&mut g, &[b"APPEND", key, data])?;
64 Ok(new_len)
65 }
66
67 pub fn hsetnx(&self, key: &[u8], field: &[u8], value: &[u8]) -> KevyResult<bool> {
73 ensure_writable(self)?;
74 let mut g = self.wshard(key);
75 let ok = g.store.hsetnx(key, field, value).map_err(store_err)?;
76 if ok {
77 commit_write(&mut g, &[b"HSETNX", key, field, value])?;
78 }
79 Ok(ok)
80 }
81
82 pub fn ttl_secs(&self, key: &[u8]) -> i64 {
88 let ms = self.ttl_ms(key);
89 if ms <= 0 { ms } else { ms / 1000 }
90 }
91}