luaur_analysis/functions/
flatten_pack_with_path.rs1use crate::enums::pack_field::PackField;
3use crate::functions::end_type_pack::end;
4use crate::functions::get_type_pack::get_type_pack_id;
5use crate::records::generic_type_pack::GenericTypePack;
6use crate::records::path::Path;
7use crate::records::type_pack::TypePack;
8use crate::records::type_pack_iterator::TypePackIterator;
9use crate::type_aliases::component::Component;
10use crate::type_aliases::type_id::TypeId;
11use crate::type_aliases::type_pack_id::TypePackId;
12
13pub fn flatten_pack_with_path(root: TypePackId, path: &Path) -> TypePack {
14 let mut flattened: alloc::vec::Vec<TypeId> = alloc::vec::Vec::new();
15
16 let mut curr: Option<TypePackId> = Some(root);
17 let mut path_iter: usize = 0;
18 let path_end = path.components.len();
19
20 while let Some(curr_pack) = curr {
21 let mut it = TypePackIterator::type_pack_iterator();
22 it.type_pack_iterator_type_pack_id(curr_pack);
23
24 while it.operator_ne(&end(curr_pack)) {
26 flattened.push(*it.operator_deref());
27 it.operator_inc();
28 }
29
30 curr = it.tail();
33 let has_generic_tail = match curr {
34 Some(tail) => !unsafe { get_type_pack_id::<GenericTypePack>(tail) }.is_null(),
35 None => false,
36 };
37 if !has_generic_tail || path_iter == path_end {
38 break;
39 }
40
41 match path.components.get(path_iter) {
44 Some(Component::PackField(pf)) if *pf == PackField::Tail => {}
45 _ => break,
46 }
47
48 path_iter += 1;
49
50 let gpm = match path.components.get(path_iter) {
53 Some(Component::GenericPackMapping(gpm)) => *gpm,
54 _ => break,
55 };
56
57 path_iter += 1;
58 curr = Some(gpm.mappedType);
59 }
60
61 TypePack {
62 head: flattened,
63 tail: curr,
64 }
65}