1use id_arena::Arena;
2
3use crate::{FunctionType, Pair, Type, TypeId, substitute};
4
5pub fn extract_pairs(arena: &mut Arena<Type>, id: TypeId) -> Vec<Pair> {
6 let id = substitute(arena, id);
7 extract_pairs_impl(arena, id).unwrap_or_default()
8}
9
10fn extract_pairs_impl(arena: &Arena<Type>, id: TypeId) -> Option<Vec<Pair>> {
11 match arena[id].clone() {
12 Type::Apply(_) => unreachable!(),
13 Type::Ref(id) => extract_pairs_impl(arena, id),
14 Type::Unresolved => Some(vec![]),
15 Type::Generic | Type::Never | Type::Atom(_) | Type::Function(_) => None,
16 Type::Pair(pair) => Some(vec![pair]),
17 Type::Struct(ty) => extract_pairs_impl(arena, ty.inner),
18 Type::Alias(alias) => extract_pairs_impl(arena, alias.inner),
19 Type::Union(ty) => {
20 let mut pairs = Vec::new();
21
22 for ty in ty.types {
23 pairs.extend(extract_pairs_impl(arena, ty)?);
24 }
25
26 Some(pairs)
27 }
28 }
29}
30
31pub fn extract_functions(arena: &mut Arena<Type>, id: TypeId) -> Vec<FunctionType> {
32 let id = substitute(arena, id);
33 extract_functions_impl(arena, id).unwrap_or_default()
34}
35
36fn extract_functions_impl(arena: &Arena<Type>, id: TypeId) -> Option<Vec<FunctionType>> {
37 match arena[id].clone() {
38 Type::Apply(_) => unreachable!(),
39 Type::Ref(id) => extract_functions_impl(arena, id),
40 Type::Unresolved | Type::Never => Some(vec![]),
41 Type::Generic | Type::Atom(_) | Type::Pair(_) => None,
42 Type::Function(function) => Some(vec![function]),
43 Type::Struct(ty) => extract_functions_impl(arena, ty.inner),
44 Type::Alias(alias) => extract_functions_impl(arena, alias.inner),
45 Type::Union(ty) => {
46 let mut pairs = Vec::new();
47
48 for ty in ty.types {
49 pairs.extend(extract_functions_impl(arena, ty)?);
50 }
51
52 Some(pairs)
53 }
54 }
55}