Skip to main content

luaur_analysis/functions/
create_union.rs

1use crate::functions::alloc_type_user_data::alloc_type_user_data;
2use crate::functions::get_type_function_runtime_alt_o::get_type_function_type_id;
3use crate::functions::get_type_user_data::get_type_user_data;
4use crate::functions::push_type::push_type;
5use crate::records::type_function_never_type::TypeFunctionNeverType;
6use crate::records::type_function_union_type::TypeFunctionUnionType;
7use crate::type_aliases::lua_state::lua_State;
8use crate::type_aliases::type_function_type_id::TypeFunctionTypeId;
9use crate::type_aliases::type_function_type_variant::TypeFunctionTypeVariant;
10use alloc::vec::Vec;
11use luaur_vm::functions::lua_gettop::lua_gettop;
12
13pub unsafe fn create_union(l: *mut lua_State) -> core::ffi::c_int {
14    let vm_l = l as *mut luaur_vm::records::lua_state::lua_State;
15    let arg_size = lua_gettop(vm_l);
16    let mut components: Vec<TypeFunctionTypeId> = Vec::with_capacity(arg_size as usize);
17
18    for i in 1..=arg_size {
19        let component = get_type_user_data(l, i);
20
21        if let Some(union_component) =
22            get_type_function_type_id::<TypeFunctionUnionType>(component).as_ref()
23        {
24            components.extend(union_component.components.iter().copied());
25        } else if !get_type_function_type_id::<TypeFunctionNeverType>(component).is_null() {
26            continue;
27        } else {
28            components.push(component);
29        }
30    }
31
32    if components.is_empty() {
33        alloc_type_user_data(
34            l,
35            TypeFunctionTypeVariant::Never(TypeFunctionNeverType::default()),
36            false,
37        );
38    } else if components.len() == 1 {
39        push_type(l, components[0]);
40    } else {
41        alloc_type_user_data(
42            l,
43            TypeFunctionTypeVariant::Union(TypeFunctionUnionType { components }),
44            false,
45        );
46    }
47
48    1
49}