use itoa::Buffer;
pub const RESP_ERR_CLUSTERDOWN: &str = "CLUSTERDOWN Hash slot not served";
pub const RESP_ERR_TRYAGAIN: &str = "TRYAGAIN Multiple keys request during rehashing of slot";
pub const RESP_ERR_INVALID_SLOT: &str = "ERR Invalid or out of range slot";
pub const RESP_ERR_GENERIC_SLOT_OUT_OFF_RANGE: &str = "ERR Slot out of range";
pub const RESP_ERR_GENERIC_CONFIG_EPOCH_ASSIGNMENT: &str =
"ERR The user can assign a config epoch only when the node does not know any other node";
pub const RESP_ERR_GENERIC_CONFIG_UPDATE: &str = "ERR Updating the config epoch";
pub const RESP_ERR_RESET_WITH_KEYS_ASSIGNED: &str =
"ERR CLUSTER RESET can't be called with master nodes containing keys";
pub const RESP_ERR_GENERIC_CANNOT_FORGET_MYSELF: &str =
"ERR I tried hard but I can't forget myself";
pub const RESP_ERR_GENERIC_CANNOT_FORGET_MY_PRIMARY: &str = "ERR Can't forget my primary";
pub const RESP_ERR_GENERIC_CANNOT_FAILOVER_FROM_NON_MASTER: &str =
"ERR Cannot failover a non-master node";
pub const RESP_ERR_GENERIC_UNKNOWN_ENDPOINT: &str = "ERR Unknown endpoint";
pub const RESP_ERR_GENERIC_SLOT_STATE: &str = "ERR Invalid slot state";
pub const RESP_ERR_MULTI_LOG_DISABLED: &str = "ERR Multi-log disabled";
pub const RESP_ERR_IOERR: &str = "IOERR Migrate keys failed";
pub const RESP_ERR_GENERIC_VALUE_IS_NOT_BOOLEAN: &str = "ERR value is not a boolean.";
pub const RESP_ERR_GENERIC_REPLICATION_AOF_TURNEDOFF: &str = "ERR Replication unaivalable because AOF is switched off, please restart replica with --aof option";
pub const RESP_ERR_UNEXPECTED_CLUSTER_CMD: &[u8] = b"-ERR unexpected cluster command\r\n";
pub const RESP_ERR_MALFORMED_APPENDLOG_FRAME: &[u8] = b"-ERR malformed APPENDLOG frame\r\n";
pub const RESP_ERR_PROTOCOL_ERROR_PREFIX: &[u8] = b"-ERR Protocol Error: ";
#[inline]
pub fn write_slot_duplicate_error(output: &mut Vec<u8>, slot: i64) {
let mut buf = Buffer::new();
output.extend_from_slice(b"-ERR Slot ");
output.extend_from_slice(buf.format(slot).as_bytes());
output.extend_from_slice(b" specified multiple times\r\n");
}
#[inline]
pub fn write_slot_range_error(output: &mut Vec<u8>, start: i64, end: i64) {
let mut buf = Buffer::new();
output.extend_from_slice(b"-ERR Invalid range ");
output.extend_from_slice(buf.format(start).as_bytes());
output.extend_from_slice(b" > ");
output.extend_from_slice(buf.format(end).as_bytes());
output.extend_from_slice(b"!\r\n");
}
#[inline]
pub fn write_redirect_error(
output: &mut Vec<u8>,
kind: &str,
slot: u16,
endpoint: &str,
port: i32,
) {
let mut buf = Buffer::new();
output.push(b'-');
output.extend_from_slice(kind.as_bytes());
output.push(b' ');
output.extend_from_slice(buf.format(slot).as_bytes());
output.push(b' ');
output.extend_from_slice(endpoint.as_bytes());
output.push(b':');
output.extend_from_slice(buf.format(port).as_bytes());
output.extend_from_slice(b"\r\n");
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn unexpected_cluster_cmd_is_wire_ready() {
assert_eq!(
RESP_ERR_UNEXPECTED_CLUSTER_CMD,
b"-ERR unexpected cluster command\r\n"
);
assert_eq!(
RESP_ERR_MALFORMED_APPENDLOG_FRAME,
b"-ERR malformed APPENDLOG frame\r\n"
);
assert_eq!(RESP_ERR_PROTOCOL_ERROR_PREFIX, b"-ERR Protocol Error: ");
}
#[test]
fn duplicate_slot_error_frames_number() {
let mut out = Vec::new();
write_slot_duplicate_error(&mut out, 3999);
assert_eq!(out, b"-ERR Slot 3999 specified multiple times\r\n");
let mut out = Vec::new();
write_slot_duplicate_error(&mut out, 0);
assert_eq!(out, b"-ERR Slot 0 specified multiple times\r\n");
}
#[test]
fn invalid_slot_range_error_frames_both_endpoints() {
let mut out = Vec::new();
write_slot_range_error(&mut out, 20000, 10000);
assert_eq!(out, b"-ERR Invalid range 20000 > 10000!\r\n");
let mut out = Vec::new();
write_slot_range_error(&mut out, 10, 5);
assert_eq!(out, b"-ERR Invalid range 10 > 5!\r\n");
}
#[test]
fn redirect_error_frames_slot_and_endpoint() {
let mut out = Vec::new();
write_redirect_error(&mut out, "MOVED", 3999, "127.0.0.1", 7001);
assert_eq!(out, b"-MOVED 3999 127.0.0.1:7001\r\n");
let mut out = Vec::new();
write_redirect_error(&mut out, "ASK", 12000, "node2.example.com", 6379);
assert_eq!(out, b"-ASK 12000 node2.example.com:6379\r\n");
}
}