use zeroize::Zeroize;
use crate::ejsonpath::{DotArg, IndexArg, Selector};
pub(crate) trait Mac {
fn mac<M>(&self, state: &mut M)
where
M: Macca;
}
pub(crate) trait Macca: Zeroize {
fn update(&mut self, bytes: &[u8]);
fn finalize_reset<const N: usize>(&mut self) -> [u8; N];
}
impl Mac for Selector {
fn mac<M>(&self, state: &mut M)
where
M: Macca,
{
const SELECTOR_ROOT: &[u8] = "SEL:ROO".as_bytes();
const SELECTOR_DOT: &[u8] = "SEL:DOT".as_bytes();
const SELECTOR_INDEX: &[u8] = "SEL:IDX".as_bytes();
match self {
Selector::Root => state.update(SELECTOR_ROOT),
Selector::Dot(selector, dot_arg) => {
state.update(SELECTOR_DOT);
selector.mac(state);
dot_arg.mac(state);
}
Selector::Index(selector, index_arg) => {
state.update(SELECTOR_INDEX);
selector.mac(state);
index_arg.mac(state);
}
}
}
}
impl Mac for DotArg {
fn mac<M>(&self, state: &mut M)
where
M: Macca,
{
const DOTARG_FIELD: &[u8] = "DOT:FLD".as_bytes();
match self {
DotArg::Field(f) => {
state.update(DOTARG_FIELD);
state.update(f.as_bytes());
}
}
}
}
impl Mac for IndexArg {
fn mac<M>(&self, state: &mut M)
where
M: Macca,
{
const INDEXARG_NUMBER: &[u8] = "IDX:NUM".as_bytes();
const INDEXARG_FIELD: &[u8] = "IDX:FLD".as_bytes();
const INDEXARG_WILDCARD: &[u8] = "IDX:WLD".as_bytes();
const INDEXARG_ITEM: &[u8] = "IDX:ITM".as_bytes();
match self {
IndexArg::Number(n) => {
state.update(INDEXARG_NUMBER);
state.update(&n.to_be_bytes()[..]);
}
IndexArg::Field(f) => {
state.update(INDEXARG_FIELD);
state.update(f.as_bytes());
}
IndexArg::Wildcard => {
state.update(INDEXARG_WILDCARD);
}
IndexArg::Item => {
state.update(INDEXARG_ITEM);
}
}
}
}
#[cfg_attr(test, derive(Debug, PartialEq, Eq))]
pub(crate) enum JsonbMacTerm {
Null,
Object,
Array,
}
impl JsonbMacTerm {
const INFO_NULL: &'static str = "NULL00";
const INFO_OBJECT: &'static str = "OBJECT";
const INFO_ARRAY: &'static str = "ARRY[]";
}
impl Mac for JsonbMacTerm {
fn mac<M>(&self, state: &mut M)
where
M: Macca,
{
match self {
JsonbMacTerm::Null => state.update(Self::INFO_NULL.as_bytes()),
JsonbMacTerm::Object => state.update(Self::INFO_OBJECT.as_bytes()),
JsonbMacTerm::Array => state.update(Self::INFO_ARRAY.as_bytes()),
}
}
}