use crate::{
db::data::{FieldDecodeError, ValueStorageView, decode_structural_value_storage_bytes},
value::Value,
};
#[derive(Clone, Debug, Eq, PartialEq)]
pub(in crate::db) struct CompiledPath {
pub(in crate::db) segments: Vec<String>,
pub(in crate::db) segment_bytes: Vec<Vec<u8>>,
}
impl CompiledPath {
#[must_use]
pub(in crate::db) fn new(segments: Vec<String>) -> Self {
let segment_bytes = segments
.iter()
.map(|segment| segment.as_bytes().to_vec())
.collect();
Self {
segments,
segment_bytes,
}
}
#[must_use]
pub(in crate::db) const fn segments(&self) -> &[String] {
self.segments.as_slice()
}
#[must_use]
pub(in crate::db) const fn segment_bytes(&self) -> &[Vec<u8>] {
self.segment_bytes.as_slice()
}
}
pub(in crate::db::executor::projection) fn resolve_path_compiled<'a>(
raw_bytes: &'a [u8],
path: &CompiledPath,
) -> Result<Option<&'a [u8]>, FieldDecodeError> {
let mut current = ValueStorageView::from_raw(raw_bytes)?;
for segment in path.segment_bytes() {
current = match current.map_text_key_bytes(segment)? {
Some(next) => next,
None => return Ok(None),
};
}
Ok(Some(current.as_bytes()))
}
pub(in crate::db::executor::projection) fn resolve_and_decode(
raw_bytes: &[u8],
path: &CompiledPath,
) -> Result<Option<Value>, FieldDecodeError> {
let Some(value_bytes) = resolve_path_compiled(raw_bytes, path)? else {
return Ok(None);
};
decode_structural_value_storage_bytes(value_bytes).map(Some)
}