use wdev::Device;
use wkv::BatchStoreSession;
use crate::resp::{cmd_strings::write_error_raw, resp_server_session::RespServerSession};
pub(crate) use crate::storage::session::objectstore::common::{
OBJ_TAG_HASH, OBJ_TAG_LIST, OBJ_TAG_SET, OBJ_TAG_SORTED_SET, obj_decode, obj_encode,
};
const GENERIC_ERR_WRONG_NUM_ARGS: &str = "ERR wrong number of arguments for '{name}' command";
impl RespServerSession {
pub fn abort_with_wrong_number_of_arguments(
&mut self,
cmd_name: &str,
output: &mut Vec<u8>,
) -> bool {
write_error_raw(
output,
&GENERIC_ERR_WRONG_NUM_ARGS.replace("{name}", cmd_name),
);
true
}
pub fn abort_with_error_message(&mut self, error_message: &[u8], output: &mut Vec<u8>) -> bool {
output.push(b'-');
output.extend_from_slice(error_message);
output.extend_from_slice(b"\r\n");
true
}
}
pub(super) enum SyncObj {
Missing,
WrongType,
Present(Vec<u8>),
}
pub(super) fn obj_load_sync<D: Device>(
store: &BatchStoreSession<'_, D>,
key: &[u8],
tag: u8,
) -> wkv::Result<Option<SyncObj>> {
Ok(Some(match store.try_read_sync(key, |v| v.to_vec())? {
None => return Ok(None),
Some(None) => SyncObj::Missing,
Some(Some(raw)) => match obj_decode(&raw, tag) {
None => SyncObj::WrongType,
Some(p) => SyncObj::Present(p.to_vec()),
},
}))
}
pub(super) fn obj_save_sync<D: Device>(
store: &BatchStoreSession<'_, D>,
key: &[u8],
tag: u8,
payload: &[u8],
) -> wkv::Result<bool> {
let val = obj_encode(tag, payload);
Ok(store.try_upsert_sync(key, &val)?.is_ok())
}
pub(super) fn obj_save_or_gc_sync<D: Device>(
store: &BatchStoreSession<'_, D>,
key: &[u8],
tag: u8,
payload: &[u8],
now_empty: bool,
) -> wkv::Result<bool> {
if now_empty {
return Ok(store.try_delete_sync(key)?.is_ok());
}
obj_save_sync(store, key, tag, payload)
}
#[cfg(test)]
mod abort_tests {
use super::*;
#[test]
fn abort_frames_match_csharp_text() {
let mut sess = RespServerSession::default();
let mut out = Vec::new();
assert!(sess.abort_with_wrong_number_of_arguments("ZADD", &mut out));
assert_eq!(
out,
b"-ERR wrong number of arguments for 'ZADD' command\r\n"
);
out.clear();
assert!(sess.abort_with_error_message(b"ERR custom", &mut out));
assert_eq!(out, b"-ERR custom\r\n");
}
}