pub trait TrendExt: Sized {
fn to_trend<'a>(&'a self, end: &'a Self) -> Trend<'a, Self>;
}
impl<T> TrendExt for T
where
T: Ord,
{
fn to_trend<'a>(&'a self, end: &'a Self) -> Trend<'a, Self> {
use std::cmp::Ordering;
match self.cmp(end) {
Ordering::Greater => Trend::Falling { start: self, end },
Ordering::Less => Trend::Rising { start: self, end },
Ordering::Equal => Trend::Stable { start: self, end },
}
}
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum Trend<'a, T> {
Rising { start: &'a T, end: &'a T },
Falling { start: &'a T, end: &'a T },
Stable { start: &'a T, end: &'a T },
}
impl<'a, T> Trend<'a, T> {
pub fn is_rising(&self) -> bool {
matches!(self, Self::Rising { .. })
}
pub fn is_falling(&self) -> bool {
matches!(self, Self::Falling { .. })
}
pub fn is_stable(&self) -> bool {
matches!(self, Self::Stable { .. })
}
pub fn start(&self) -> &'a T {
match self {
Self::Rising { start, .. }
| Self::Falling { start, .. }
| Self::Stable { start, .. } => *start,
}
}
pub fn end(&self) -> &'a T {
match self {
Self::Rising { end, .. } | Self::Falling { end, .. } | Self::Stable { end, .. } => *end,
}
}
pub fn clone_start(&self) -> T
where
T: Clone,
{
match self {
Self::Rising { start, .. }
| Self::Falling { start, .. }
| Self::Stable { start, .. } => (*start).clone(),
}
}
pub fn clone_end(&self) -> T
where
T: Clone,
{
match self {
Self::Rising { end, .. } | Self::Falling { end, .. } | Self::Stable { end, .. } => {
(*end).clone()
}
}
}
pub fn direction(&self) -> i8 {
if self.is_stable() {
0
} else if self.is_rising() {
1
} else {
-1
}
}
}