Skip to main content

luaur_analysis/functions/
flatten_pack_with_path.rs

1//! Source: `Analysis/src/TypePath.cpp:1107-1141` (hand-ported)
2use 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        // Push back curr's head
25        while it.operator_ne(&end(curr_pack)) {
26            flattened.push(*it.operator_deref());
27            it.operator_inc();
28        }
29
30        // Check if curr has a tail, and if the next bit of path is Tail +
31        // GenericPackMapping
32        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        // const TypePath::PackField* pf = get_if<PackField>(&*pathIter);
42        // if (!pf || *pf != Tail) break;
43        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        // const GenericPackMapping* gpm = get_if<GenericPackMapping>(&*pathIter);
51        // if (!gpm) break;
52        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}