use crate::{
context::Context,
views::{View, ViewError, MIN_VIEW_TAG},
};
#[repr(u8)]
pub(crate) enum KeyTag {
Index = MIN_VIEW_TAG,
Subview,
}
pub(crate) fn index_key<C: Context>(context: &C, short_key: &[u8]) -> Vec<u8> {
context
.base_key()
.base_tag_index(KeyTag::Index as u8, short_key)
}
pub(crate) fn subview_key<C: Context>(context: &C, short_key: &[u8]) -> Vec<u8> {
context
.base_key()
.base_tag_index(KeyTag::Subview as u8, short_key)
}
pub(crate) fn subview_context<C: Context>(context: &C, short_key: &[u8]) -> C {
context.clone_with_base_key(subview_key(context, short_key))
}
pub(crate) fn entry_len<W: View>() -> usize {
1 + W::NUM_INIT_KEYS
}
pub(crate) fn entry_keys<W: View>(
context: &W::Context,
short_key: &[u8],
) -> Result<(W::Context, Vec<Vec<u8>>), ViewError> {
let subview_context = subview_context(context, short_key);
let mut keys = Vec::with_capacity(entry_len::<W>());
keys.push(index_key(context, short_key));
keys.extend(W::pre_load(&subview_context)?);
Ok((subview_context, keys))
}
pub(crate) fn post_load_entry<W: View>(
subview_context: W::Context,
values: &[Option<Vec<u8>>],
) -> Result<Option<W>, ViewError> {
let (marker, init_values) = values.split_first().ok_or(ViewError::PostLoadValuesError)?;
if marker.is_none() {
return Ok(None);
}
Ok(Some(W::post_load(subview_context, init_values)?))
}