use crate::core::Method;
use crate::core::{ValueType, OHLCV};
use std::ops::Add;
pub trait Sequence<T>: AsRef<[T]> {
fn validate(&self) -> bool;
#[inline]
fn call<M>(&self, method: &mut M) -> Vec<M::Output>
where
M: Method<Input = T>,
{
self.as_ref().iter().map(|x| method.next(x)).collect()
}
#[inline]
fn apply<M>(&mut self, method: &mut M)
where
M: Method<Input = T, Output = T>,
Self: AsMut<[T]>,
{
self.as_mut().iter_mut().for_each(|x| *x = method.next(x));
}
#[inline]
fn get_initial_value(&self) -> Option<&T> {
self.as_ref().first()
}
#[inline]
fn get_initial_value_mut(&mut self) -> Option<&mut T>
where
Self: AsMut<[T]>,
{
self.as_mut().first_mut()
}
fn collapse_timeframe(&self, size: usize, continuous: bool) -> Vec<T>
where
T: OHLCV + Clone + Add<Output = T>,
{
#[inline]
fn reduce<T: OHLCV + Clone + Add<Output = T>>(window: &[T]) -> T {
window.iter().cloned().reduce(Add::add).unwrap()
}
self.as_ref()
.windows(size)
.step_by(if continuous { 1 } else { size })
.map(reduce)
.collect()
}
}
impl<Q: AsRef<[ValueType]>> Sequence<ValueType> for Q {
#[inline]
fn validate(&self) -> bool {
self.as_ref().iter().copied().all(ValueType::is_finite)
}
}
impl<T: OHLCV, Q: AsRef<[T]>> Sequence<T> for Q {
#[inline]
fn validate(&self) -> bool {
self.as_ref().iter().all(OHLCV::validate)
}
}