pub mod states;
pub mod types;
use self::{states::*, types::TransitionFunction};
use crate::sequence_part::{
error::RangeError,
types::{
AliveElementsPart, RangePartImmut, RangePartImmutResult, RangePartMut, RangePartMutResult,
},
};
pub struct Sequence<T, I, F> {
initial_elements: I,
trans_func: F,
alive_elements: Vec<T>,
iter_index: usize,
}
pub trait SharedSequenceBehavior {
fn pre_generate(self, number_of_elements: usize) -> Self;
fn clear(&mut self);
}
impl<T> Default for Sequence<T, WithoutInitialElements, WithoutTransitionFunction> {
fn default() -> Self {
Self {
initial_elements: WithoutInitialElements,
trans_func: WithoutTransitionFunction,
alive_elements: Vec::new(),
iter_index: 0,
}
}
}
impl<T> Sequence<T, WithoutInitialElements, WithoutTransitionFunction> {
pub fn new() -> Self {
Sequence::default()
}
pub fn initial_elements(
self,
initial_elements: Vec<T>,
) -> Sequence<T, WithInitialElements, WithoutTransitionFunction> {
Sequence {
initial_elements: WithInitialElements::new(initial_elements.len()),
trans_func: self.trans_func,
alive_elements: initial_elements,
iter_index: self.iter_index,
}
}
}
impl<T, F> Sequence<T, WithInitialElements, F> {
pub fn initial_elements_len(&self) -> usize {
self.initial_elements.len()
}
}
impl<T, I> Sequence<T, I, WithoutTransitionFunction> {
pub fn transition_function(
self,
trans_func: TransitionFunction<T, I>,
) -> Sequence<T, I, WithTransitionFunction<T, I>> {
Sequence {
initial_elements: self.initial_elements,
trans_func: WithTransitionFunction::new(trans_func),
alive_elements: self.alive_elements,
iter_index: self.iter_index,
}
}
}
impl<T, I> Sequence<T, I, WithTransitionFunction<T, I>> {
fn generate_nth_element(&mut self, nth_element: usize) {
if !self.nth_element_is_alive(nth_element) {
let alive_elements_len = self.alive_elements_len();
for current_element_index in alive_elements_len..=nth_element {
let alive_elements_part = self.alive_elements();
let new_element = self
.trans_func
.run(alive_elements_part, current_element_index);
self.alive_elements.push(new_element);
}
}
}
pub(crate) fn nth_element_without_generation(&self, index: usize) -> Option<&T> {
if !self.nth_element_is_alive(index) {
return None;
}
Some(&self.alive_elements[index])
}
pub fn generate(&mut self, number_of_elements: usize) {
self.generate_nth_element(self.alive_elements_len() + number_of_elements - 1);
}
pub fn alive_elements_len(&self) -> usize {
self.alive_elements.len()
}
pub fn nth_element_is_alive(&self, index: usize) -> bool {
index < self.alive_elements_len()
}
pub fn nth_element(&mut self, index: usize) -> &T {
self.generate_nth_element(index);
&self.alive_elements[index]
}
pub fn alive_elements(&self) -> AliveElementsPart<'_, T, I> {
AliveElementsPart::new(self)
}
pub fn range(&self, start: usize, end: usize) -> RangePartImmutResult<'_, T, I> {
if start > end {
return Err(RangeError::InvalidRange { start, end });
}
if !self.nth_element_is_alive(end - 1) {
return Err(RangeError::DeadRange);
}
Ok(RangePartImmut::new_range(self, start, end))
}
pub fn range_mut(&mut self, start: usize, end: usize) -> RangePartMutResult<'_, T, I> {
if start > end {
return Err(RangeError::InvalidRange { start, end });
}
Ok(RangePartMut::new_range_mut(self, start, end))
}
}
impl
Sequence<usize, WithoutInitialElements, WithTransitionFunction<usize, WithoutInitialElements>>
{
pub fn linear_seq() -> Self {
Sequence::new().transition_function(|_, i| i)
}
}
impl<T> SharedSequenceBehavior
for Sequence<T, WithInitialElements, WithTransitionFunction<T, WithInitialElements>>
{
fn pre_generate(mut self, number_of_elements: usize) -> Self {
if number_of_elements > 0 {
let initial_elements_len = self.initial_elements_len();
let last_generated_element = number_of_elements - 1 + initial_elements_len;
self.generate_nth_element(last_generated_element);
}
self
}
fn clear(&mut self) {
let mut initial_elements = Vec::new();
for index in 0..self.initial_elements_len() {
initial_elements.push(self.alive_elements.remove(index));
}
self.alive_elements = initial_elements;
}
}
impl<T> SharedSequenceBehavior
for Sequence<T, WithoutInitialElements, WithTransitionFunction<T, WithoutInitialElements>>
{
fn pre_generate(mut self, number_of_elements: usize) -> Self {
if number_of_elements != 0 {
self.generate_nth_element(number_of_elements - 1);
}
self
}
fn clear(&mut self) {
self.alive_elements = Vec::new();
}
}
impl<T: Clone, I> Iterator for Sequence<T, I, WithTransitionFunction<T, I>> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
let iter_index = self.iter_index;
if iter_index == std::usize::MAX {
self.iter_index = 0;
return None;
}
self.iter_index += 1;
Some(self.nth_element(iter_index).clone())
}
}