use bitcode::{Decode, Encode};
use strum::{AsRefStr, Display, FromRepr, IntoStaticStr};
use crate::error::{Error, Result};
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
Hash,
PartialOrd,
Ord,
FromRepr,
Display,
AsRefStr,
IntoStaticStr,
Encode,
Decode,
)]
#[repr(u8)]
pub enum KeyTag {
String = 0x00,
Meta = 0x01,
Hash = 0x02,
Set = 0x03,
ZSetChunk = 0x04,
ZSetM2s = 0x05,
ListChunk = 0x06,
HashChunk = 0x07,
SetChunk = 0x08,
Ttl = 0x09,
}
impl KeyTag {
pub const HASH_FIELD: Self = Self::Hash;
pub const SET_MEMBER: Self = Self::Set;
pub const Z_MEMBER: Self = Self::ZSetChunk;
pub const Z_SCORE: Self = Self::ZSetM2s;
pub const TTL_RECORD: Self = Self::Ttl;
pub const TAG_LEN: usize = 1;
#[inline(always)]
pub const fn from_u8(val: u8) -> Option<Self> {
Self::from_repr(val)
}
#[inline(always)]
pub const fn as_u8(self) -> u8 {
self as u8
}
#[inline(always)]
pub const fn as_str(self) -> &'static str {
match self {
Self::String => "String",
Self::Meta => "Meta",
Self::Hash => "Hash",
Self::Set => "Set",
Self::ZSetChunk => "ZSetChunk",
Self::ZSetM2s => "ZSetM2s",
Self::ListChunk => "ListChunk",
Self::HashChunk => "HashChunk",
Self::SetChunk => "SetChunk",
Self::Ttl => "Ttl",
}
}
#[inline(always)]
pub const fn prefix(self) -> [u8; Self::TAG_LEN] {
[self as u8]
}
#[inline(always)]
pub const fn strip_prefix(self, key: &[u8]) -> Option<&[u8]> {
match key {
[first, rest @ ..] if *first == self as u8 => Some(rest),
_ => None,
}
}
#[inline(always)]
pub const fn is_subkey(self) -> bool {
let v = self as u8;
v >= Self::Hash as u8 && v <= Self::SetChunk as u8
}
#[inline(always)]
pub const fn is_user_visible(self) -> bool {
matches!(self, Self::String | Self::Meta)
}
}
impl TryFrom<u8> for KeyTag {
type Error = Error;
#[inline]
fn try_from(val: u8) -> Result<Self> {
Self::from_repr(val).ok_or(Error::InvalidKeyTag(val))
}
}
impl From<KeyTag> for u8 {
#[inline(always)]
fn from(tag: KeyTag) -> Self {
tag as Self
}
}
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
Hash,
PartialOrd,
Ord,
FromRepr,
Default,
Display,
AsRefStr,
IntoStaticStr,
Encode,
Decode,
)]
#[strum(serialize_all = "lowercase")]
#[repr(u8)]
pub enum CollectionType {
#[default]
Hash = 1,
Set = 2,
ZSet = 3,
List = 4,
RangeIndex = 5,
}
impl CollectionType {
#[inline(always)]
pub const fn from_u8(val: u8) -> Option<Self> {
Self::from_repr(val)
}
#[inline(always)]
pub const fn as_u8(self) -> u8 {
self as u8
}
#[inline(always)]
pub const fn as_str(self) -> &'static str {
match self {
Self::Hash => "hash",
Self::Set => "set",
Self::ZSet => "zset",
Self::List => "list",
Self::RangeIndex => "rangeindex",
}
}
}
impl TryFrom<u8> for CollectionType {
type Error = Error;
#[inline]
fn try_from(val: u8) -> Result<Self> {
Self::from_repr(val).ok_or(Error::InvalidCollectionType(val))
}
}
impl From<CollectionType> for u8 {
#[inline(always)]
fn from(t: CollectionType) -> Self {
t as Self
}
}