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 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 GarnetObjectType {
#[default]
Null = 0,
#[strum(serialize = "zset")]
SortedSet = 1,
#[strum(serialize = "list")]
List = 2,
#[strum(serialize = "hash")]
Hash = 3,
#[strum(serialize = "set")]
Set = 4,
#[strum(serialize = "rangeindex")]
RangeIndex = 5,
#[strum(serialize = "all")]
All = 0xfb,
}
impl GarnetObjectType {
pub const ZSET: Self = Self::SortedSet;
#[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::Null => "null",
Self::SortedSet => "zset",
Self::List => "list",
Self::Hash => "hash",
Self::Set => "set",
Self::RangeIndex => "rangeindex",
Self::All => "all",
}
}
}
impl TryFrom<u8> for GarnetObjectType {
type Error = Error;
#[inline]
fn try_from(val: u8) -> Result<Self> {
Self::from_repr(val).ok_or(Error::InvalidCollectionType(val))
}
}
impl From<GarnetObjectType> for u8 {
#[inline(always)]
fn from(t: GarnetObjectType) -> Self {
t as Self
}
}
pub type CollectionType = GarnetObjectType;