intervals_rs/
limit_value.rs

1use std::cmp::Ordering;
2use std::fmt::{Display, Formatter, Debug};
3
4use crate::Error;
5use std::hash::{Hash, Hasher};
6
7/// A structure that represents a limit value.
8#[derive(Debug, Clone, Eq, Ord)]
9pub enum LimitValue<T> {
10  /// finite limit value
11  Limit(T),
12  /// infinite limit value
13  Limitless,
14}
15
16impl<T: ToString> Hash for LimitValue<T> {
17  fn hash<H: Hasher>(&self, state: &mut H) {
18    match self {
19      LimitValue::Limit(value) => {
20        "Limit".hash(state);
21        value.to_string().hash(state)
22      }
23      LimitValue::Limitless => {
24        "Limitless".hash(state);
25      }
26    }
27  }
28}
29
30impl<T: Default> Default for LimitValue<T> {
31  fn default() -> Self {
32    LimitValue::Limit(T::default())
33  }
34}
35
36impl<T: PartialEq> PartialEq for LimitValue<T> {
37  fn eq(&self, other: &Self) -> bool {
38    match (self, other) {
39      (LimitValue::Limitless, LimitValue::Limitless) => true,
40      (LimitValue::Limit(value), LimitValue::Limit(other_value)) => value == other_value,
41      _ => false,
42    }
43  }
44}
45
46impl<T: PartialOrd> PartialOrd for LimitValue<T> {
47  fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
48    match (self, other) {
49      (LimitValue::Limitless, LimitValue::Limitless) => Some(Ordering::Equal),
50      (LimitValue::Limit(_), LimitValue::Limitless) => Some(Ordering::Greater),
51      (LimitValue::Limitless, LimitValue::Limit(_)) => Some(Ordering::Less),
52      (LimitValue::Limit(value), LimitValue::Limit(other_value)) => value.partial_cmp(other_value),
53    }
54  }
55}
56
57impl<T> From<Option<T>> for LimitValue<T> {
58  fn from(value: Option<T>) -> Self {
59    match value {
60      None => LimitValue::Limitless,
61      Some(v) => LimitValue::Limit(v),
62    }
63  }
64}
65
66impl<T> LimitValue<T> {
67  /// Verify if this limit is finite.
68  pub fn is_limit(&self) -> bool {
69    matches!(self, LimitValue::Limit(_))
70  }
71
72  /// Verify if this limit is infinite.
73  pub fn is_limitless(&self) -> bool {
74    matches!(self, LimitValue::Limitless)
75  }
76
77  /// Get the limit value.
78  pub fn as_value(&self) -> Result<&T, Error> {
79    match self {
80      LimitValue::Limit(a) => Ok(a),
81      LimitValue::Limitless => Err(Error::NotFoundError),
82    }
83  }
84
85  /// Get the limit value.
86  pub fn as_value_or<'a, TF>(&'a self, default: TF) -> &T
87  where
88    TF: Fn() -> &'a T,
89  {
90    match self {
91      LimitValue::Limit(a) => a,
92      LimitValue::Limitless => default(),
93    }
94  }
95}
96
97impl<T: Display> Display for LimitValue<T> {
98  fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
99    match self {
100      LimitValue::Limit(a) => write!(f, "Limit({})", a),
101      LimitValue::Limitless => write!(f, "Limitless"),
102    }
103  }
104}