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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
//! This module defines the SequencePart type
//! that represents a part of a Sequence type.
//!
//! A sequence part could be alive elements part
//! that represents the alive elements of the sequence (Generated elements)
//! or range part (custom range) that represents a range of a sequence.
//!
//! The range parts are lazy and can mutate the sequence.
//! The alive part can not mutate the sequence.

pub(crate) mod states;
pub(crate) mod types;

pub mod error;

use self::{
    states::*,
    types::{AliveElementsPart, ParentSequenceRef, ParentSequenceRefMut, RangePart},
};

/// This type represents a part of a sequence.
/// it could be the alive elements or a range of the sequence.
pub struct SequencePart<P, S> {
    part: P,
    parent_sequence: S,
    iter_index: usize,
}

/// Shared behavior between range part and alive elements part.
pub trait SharedSequencePartBehavior<T> {
    /// Returns the length of the sequence part.
    fn len(&self) -> usize;

    /// Checks if the sequence part is empty.
    fn is_empty(&self) -> bool {
        self.len() == 0
    }
}

impl<'a, T, I> AliveElementsPart<'a, T, I> {
    /// Create a new instance that represents the alive elements
    pub(super) fn new(parent_sequence: ParentSequenceRef<'a, T, I>) -> AliveElementsPart<'a, T, I> {
        SequencePart {
            parent_sequence,
            part: AliveElements,
            iter_index: 0,
        }
    }

    /// Returns the nth elements of the alive elements
    pub fn nth_element(&self, index: usize) -> Option<&T> {
        self.parent_sequence.nth_element_without_generation(index)
    }

    /// Returns the first element of the alive part.
    pub fn first_element(&self) -> Option<&T> {
        self.nth_element(0)
    }

    /// Returns the last element of the alive part.
    pub fn last_element(&self) -> Option<&T> {
        if self.is_empty() {
            return None;
        }

        self.nth_element(self.len() - 1)
    }
}

impl<'a, T, I> RangePart<'a, T, I> {
    /// Creates a new instance that represents a range of a sequence
    pub(super) fn new_range(
        parent_sequence: ParentSequenceRefMut<'a, T, I>,
        start: usize,
        end: usize,
    ) -> RangePart<'a, T, I> {
        SequencePart {
            parent_sequence,
            part: Range::new(start, end),
            iter_index: start,
        }
    }

    /// Checks if the element is in the range
    pub fn nth_element_is_in_range(&self, index: usize) -> bool {
        index >= self.part.start() && index < self.part.end()
    }

    /// Returns the nth elements of the range part
    pub fn nth_element(&mut self, index: usize) -> Option<&T> {
        if !self.nth_element_is_in_range(index) {
            return None;
        }

        Some(self.parent_sequence.nth_element(index))
    }

    /// Returns the first element of the range part.
    pub fn first_element(&mut self) -> Option<&T> {
        self.nth_element(self.part.start())
    }

    /// Returns the last element of the range part.
    pub fn last_element(&mut self) -> Option<&T> {
        self.nth_element(self.part.end())
    }
}

impl<'a, T, I> SharedSequencePartBehavior<T> for AliveElementsPart<'a, T, I> {
    fn len(&self) -> usize {
        self.parent_sequence.alive_elements_len()
    }
}

impl<'a, T, I> SharedSequencePartBehavior<T> for RangePart<'a, T, I> {
    fn len(&self) -> usize {
        self.part.end() - self.part.start()
    }
}

impl<'a, T: Clone, I> Iterator for AliveElementsPart<'a, T, I> {
    type Item = T;

    fn next(&mut self) -> Option<Self::Item> {
        let iter_index = self.iter_index;

        if iter_index == self.len() {
            self.iter_index = 0;
            return None;
        }

        self.iter_index += 1;
        self.nth_element(iter_index).cloned()
    }
}

impl<'a, T: Clone, I> Iterator for RangePart<'a, T, I> {
    type Item = T;

    fn next(&mut self) -> Option<Self::Item> {
        let iter_index = self.iter_index;

        if iter_index == self.part.end() {
            self.iter_index = 0;
            return None;
        }

        self.iter_index += 1;
        self.nth_element(iter_index).cloned()
    }
}