1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
use crate::ty;
use crate::ty::Ty;

/// Iterates through the member types of a list
#[derive(Clone)]
pub struct ListIterator<'list, M: ty::Pm> {
    fixed: &'list [ty::Ref<M>],
    rest: &'list ty::Ref<M>,
}

impl<'list, M: ty::Pm> ListIterator<'list, M> {
    pub fn new(list: &'list ty::List<M>) -> ListIterator<'list, M> {
        ListIterator {
            fixed: list.fixed(),
            rest: list.rest(),
        }
    }

    pub fn try_new_from_ty_ref(ty_ref: &'list ty::Ref<M>) -> Option<ListIterator<'list, M>> {
        match ty_ref.try_to_fixed() {
            Some(Ty::List(list)) => Some(Self::new(list)),
            _ => None,
        }
    }

    pub fn fixed_len(&self) -> usize {
        self.fixed.len()
    }

    pub fn has_rest(&self) -> bool {
        !self.rest.is_never()
    }

    pub fn tail_type(self) -> ty::List<M> {
        ty::List::new(self.fixed.to_vec().into_boxed_slice(), self.rest.clone())
    }

    pub fn collect_rest(self) -> ty::Ref<M> {
        use std::iter;

        if self.fixed.is_empty() {
            self.rest.clone()
        } else {
            ty::unify::unify_ty_ref_iter(self.fixed.iter().chain(iter::once(self.rest)).cloned())
        }
    }
}

impl<'list, M: ty::Pm> Iterator for ListIterator<'list, M> {
    type Item = &'list ty::Ref<M>;

    fn next(&mut self) -> Option<&'list ty::Ref<M>> {
        if self.fixed.is_empty() {
            if self.rest.is_never() {
                None
            } else {
                Some(self.rest)
            }
        } else {
            let next = self.fixed.first();
            self.fixed = &self.fixed[1..];
            next
        }
    }
}