use num::ToPrimitive;
use crate::{
store::{
defaults::{NodeIdentifier},
nodes::HashedNodeRef,
},
types::{
AnyType, Children, HyperAST, HyperType, IterableChildren, LabelStore, Labeled, NodeStore,
TypeStore, WithChildren, WithSerialization,
},
};
use super::Position;
pub(super) fn extract_file_postion<'store, HAST: HyperAST<'store>>(
stores: &'store HAST,
parents: &[HAST::IdN],
) -> Position {
if parents.is_empty() {
Position::default()
} else {
let p = &parents[parents.len() - 1];
let b = stores.node_store().resolve(p);
let l = stores.label_store().resolve(b.get_label_unchecked());
let mut r = extract_file_postion(stores, &parents[..parents.len() - 1]);
r.inc_path(l);
r
}
}
pub(super) fn extract_position<'store, HAST>(
stores: &'store HAST,
parents: &[HAST::IdN],
offsets: &[usize],
) -> Position
where
HAST: HyperAST<'store, IdN = NodeIdentifier, T = HashedNodeRef<'store>>,
HAST::TS: TypeStore<HashedNodeRef<'store>, Ty = AnyType>,
{
if parents.is_empty() {
return Position::default();
}
let p = parents[parents.len() - 1];
let o = offsets[offsets.len() - 1];
let b = stores.node_store().resolve(&p);
let c = {
let v: Vec<_> = b.children().unwrap().before(o.to_u16().unwrap() - 1).into();
v.iter()
.map(|x| {
let b = stores.node_store().resolve(x);
b.try_bytes_len().unwrap() as usize
})
.sum()
};
if stores.type_store().resolve_type(&b).is_file() {
let mut r = extract_file_postion(stores, parents);
r.inc_offset(c);
r
} else {
let mut r = extract_position(
stores,
&parents[..parents.len() - 1],
&offsets[..offsets.len() - 1],
);
r.inc_offset(c);
r
}
}
pub(super) fn extract_file_postion_it_rec<'store, HAST, It>(
stores: &'store HAST,
mut nodes: It,
) -> Position
where
HAST: HyperAST<'store>,
It: Iterator<Item = HAST::IdN>, {
let Some(p) = nodes.next() else {
return Position::default()
};
let b = stores.node_store().resolve(&p);
let l = stores.label_store().resolve(b.get_label_unchecked());
let mut r = extract_file_postion_it_rec(stores, nodes);
r.inc_path(l);
r
}
pub(super) fn extract_position_it_rec<'store, HAST, It, It2>(
stores: &'store HAST,
mut it: It,
) -> Position
where
HAST: HyperAST<'store, IdN = NodeIdentifier, Idx = u16>,
HAST::TS: TypeStore<HAST::T, Ty = AnyType>,
HAST::T: WithSerialization,
It: Iterator<Item = (HAST::IdN, usize)> + Into<It2>, It2: Iterator<Item = HAST::IdN>,
{
let Some((p,o)) = it.next() else {
return Position::default();
};
let b = stores.node_store().resolve(&p);
let c = {
let v: Vec<&HAST::IdN> = b
.children()
.unwrap()
.before(o.to_u16().unwrap() - 1)
.iter_children()
.collect();
v.into_iter()
.map(|x| {
let b = stores.node_store().resolve(x);
b.try_bytes_len().unwrap() as usize
})
.sum()
};
if stores.type_store().resolve_type(&b).is_file() {
let mut r = extract_file_postion_it_rec(stores, it.into());
{
let l = stores.label_store().resolve(b.get_label_unchecked());
r.inc_path(l);
}
r.inc_offset(c);
r
} else {
let mut r = extract_position_it_rec(stores, it);
r.inc_offset(c);
r
}
}
pub(super) fn extract_file_postion_it<'store, HAST, It>(stores: &'store HAST, nodes: It) -> Position
where
HAST: HyperAST<'store>,
It: Iterator<Item = HAST::IdN>, {
let ls: Vec<_> = nodes
.map(|p| {
let b = stores.node_store().resolve(&p);
stores.label_store().resolve(b.get_label_unchecked())
})
.collect();
let mut r = Position::default();
for l in ls.into_iter().rev() {
r.inc_path(l);
}
r
}
pub(super) fn extract_position_it<'store, HAST, It, It2>(
stores: &'store HAST,
mut it: It,
) -> Position
where
HAST: HyperAST<'store, IdN = NodeIdentifier, Idx = u16>,
HAST::TS: TypeStore<HAST::T, Ty = AnyType>,
HAST::T: WithSerialization,
It: Iterator<Item = (HAST::IdN, usize)> + Into<It2>, It2: Iterator<Item = HAST::IdN>,
{
let mut offset: usize = num::zero();
while let Some((p, o)) = it.next() {
let b = stores.node_store().resolve(&p);
let c: usize = {
let v: Vec<&HAST::IdN> = b
.children()
.unwrap()
.before(o.to_u16().unwrap() - 1)
.iter_children()
.collect();
v.into_iter()
.map(|x| {
let b = stores.node_store().resolve(x);
b.try_bytes_len().unwrap() as usize
})
.sum()
};
offset += c;
if stores.type_store().resolve_type(&b).is_file() {
let mut r = extract_file_postion_it(stores, it.into());
{
let l = stores.label_store().resolve(b.get_label_unchecked());
r.inc_path(l);
}
r.inc_offset(offset);
return r;
}
}
let mut r = Position::default();
r.inc_offset(offset);
r
}