use super::args::{self, Args, is};
use super::table::Spec;
use crate::reply::Out;
use yo_common::{Code, Error, Result};
use yo_kv::Db;
use yo_kv::hll;
const UNKNOWN_SUB: &str = "Unknown PFDEBUG subcommand";
pub(super) fn execute(db: &Db, spec: &Spec, args: Args<'_>, out: &mut Out) -> Result<()> {
match spec.name {
"pfadd" => {
let eles = (2..args.len()).map(|i| args.get(i));
let key = args.get(1);
out.int(i64::from(db.hold(key).pfadd(key, eles)?));
}
"pfcount" => {
let keys = (1..args.len()).map(|i| args.get(i));
out.uint(db.pfcount(keys)?);
}
"pfmerge" => {
let srcs = (2..args.len()).map(|i| args.get(i));
db.pfmerge(args.get(1), srcs)?;
out.ok();
}
"pfdebug" => debug(db, args, out)?,
"pfselftest" => out.ok(),
_ => return Err(args::syntax()),
}
Ok(())
}
fn debug(db: &Db, args: Args<'_>, out: &mut Out) -> Result<()> {
let (sub, key) = (args.get(1), args.get(2));
if is(sub, b"getreg") {
let mut regs = [0u8; hll::REGISTERS];
db.hold(key).pfgetreg(key, &mut regs)?;
out.array(regs.len());
for &val in ®s {
out.int(i64::from(val));
}
} else if is(sub, b"decode") {
db.hold(key).pfdecode(key, |text| out.bulk(text))?;
} else if is(sub, b"encoding") {
let enc = db.hold(key).pfencoding(key)?;
out.simple(enc.name().as_bytes());
} else if is(sub, b"todense") {
out.int(i64::from(db.hold(key).pftodense(key)?));
} else {
return Err(unknown(sub));
}
Ok(())
}
fn unknown(sub: &[u8]) -> Error {
yo_alloc::allow(|| {
Error::fmt(
Code::Unsupported,
format_args!("{UNKNOWN_SUB} '{}'", String::from_utf8_lossy(sub)),
)
})
}