use base64::{engine::general_purpose::STANDARD as BASE64, Engine as _};
use crate::commands::buffer::Buffer;
use crate::errors::Result;
use crate::msgpack::encoder::pack_ctx_for_index;
use crate::operations::lists::{list_order_flag, ListOrderType};
use crate::operations::MapOrder;
use crate::Value;
pub(crate) const DEFAULT_CTX: Vec<CdtContext> = vec![];
pub(crate) enum CtxType {
ListIndex = 0x10,
ListRank = 0x11,
ListValue = 0x13,
MapIndex = 0x20,
MapRank = 0x21,
MapKey = 0x22,
MapValue = 0x23,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CdtContext {
pub id: u8,
pub flags: u8,
pub value: Value,
}
pub fn to_base64(ctx: &[CdtContext]) -> Result<String> {
let size = pack_ctx_for_index(&mut None, ctx)?;
let mut buf = Buffer::new(0);
buf.resize_buffer(size)?;
let _ = pack_ctx_for_index(&mut Some(&mut buf), ctx);
Ok(BASE64.encode(&buf.data_buffer))
}
pub const fn ctx_list_index(index: i64) -> CdtContext {
CdtContext {
id: CtxType::ListIndex as u8,
flags: 0,
value: Value::Int(index),
}
}
pub const fn ctx_list_index_create(index: i64, order: ListOrderType, pad: bool) -> CdtContext {
CdtContext {
id: CtxType::ListIndex as u8,
flags: list_order_flag(order, pad),
value: Value::Int(index),
}
}
pub const fn ctx_list_rank(rank: i64) -> CdtContext {
CdtContext {
id: CtxType::ListRank as u8,
flags: 0,
value: Value::Int(rank),
}
}
pub const fn ctx_list_value(key: Value) -> CdtContext {
CdtContext {
id: CtxType::ListValue as u8,
flags: 0,
value: key,
}
}
pub const fn ctx_map_index(key: Value) -> CdtContext {
CdtContext {
id: CtxType::MapIndex as u8,
flags: 0,
value: key,
}
}
pub const fn ctx_map_rank(rank: i64) -> CdtContext {
CdtContext {
id: CtxType::MapRank as u8,
flags: 0,
value: Value::Int(rank),
}
}
pub const fn ctx_map_key(key: Value) -> CdtContext {
CdtContext {
id: CtxType::MapKey as u8,
flags: 0,
value: key,
}
}
pub const fn ctx_map_key_create(key: Value, order: MapOrder) -> CdtContext {
CdtContext {
id: CtxType::MapKey as u8,
flags: order.flag(),
value: key,
}
}
pub const fn ctx_map_value(key: Value) -> CdtContext {
CdtContext {
id: CtxType::MapValue as u8,
flags: 0,
value: key,
}
}